<?php
/*
Version 0.1
SEMF - Web Desiging Framework for Sport Event Managment
Copyright (C) 2006, SEMF Developers

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

*/
/**
 * handle symantic of a parse tree
 */
include_once("function.php");

class symantic_handler
{
	private $semf_root;
	private $data_vars;
	private $global_namespace;
	
	private $body_script;
	private $init_script;
	
	public $where_sql;
	public $select_sql;
	public $from_sql;
	public $sql_script;
	public $update_sql;
	public $addition_sql_lhs;
	public $addition_sql_rhs;
	public $update_where_sql;
	public $update_select_sql;
	public $update_array_table;
	public $update_array_table_entry;
	public $update_field_name;
	private $select_support_code;
	
	private $table_vars;
	private $page_js_vars;
	private $page_php_vars; // this is without table_vars..

	private $databinding_vars;
	private $js_action_vars;
	private $php_action_vars;
	private $php_inout_vars;
	private $php_table_inout_vars;
	private $databinding_updater;
	
	private $current_table;
	private $js_possible;
	
	
	public $page_namespace;
	public $table_namespace;
	
	private $php_code_on_load;
	private $js_code_on_load;
	private $php_code_on_load_init_js;
	
	private $req_semi_col;
	
	private $js_includes;
	private $php_includes;
	private $css_includes;
	
	private $property_update_code;
	private $description;
	
	private $databinding_stack;
	private $databinding_stack_head;
	
	private $component_types;
	
	private $js_code_global;
		
	private $action_element_info;
	
	private $project_home;
	private $table_info;
	
	private $error_msg;
	
	private $pre_stmt_code;
	private $pre_stmt_vars;
	private $pre_stmt_count;
	
	private $param_parser_count;
	
	/**
	 * constructor for the symantic_handler
	 * @param $semf_root root path of the semf dir.
	 * @param $global_namespace gloabal namespace for the symantic handler(not used)..
	 * @return newly created symantic_handler object..
	 */
	public function __construct($semf_root, $project_home, $global_namespace)
	{
		if($semf_root == NULL)
		{
			$this->semf_root = "../../";
		}
		else
		{
			$this->semf_root = $semf_root;
		}
		$this->global_namespace = $global_namespace;
		$this->page_namespace = "SEMF.page.";
		$this->table_namespace = "SEMF.table.";
		
		$this->error_msg = "";
		
		$this->data_vars = array();
		
		$this->init_script = "";
		$this->body_script = "";
		
		$this->table_vars = array();
		$this->page_js_vars = array();
		$this->page_php_vars = array();
		
		$this->js_action_vars = array();
		$this->php_action_vars = array();
		
		$this->databinding_vars = array();
		
		$this->php_code_on_load = "";
		$this->js_code_on_load = "";
		$this->php_code_on_load_init_js = "";
		$this->update_where_sql = "";
		$this->update_select_sql = "";
		
		$this->select_support_code = "";
		
		$this->req_semi_col = true;
		$this->php_table_inout_vars = array();
		
		$this->js_includes= "";
		$this->php_includes= "";
		$this->css_includes = "";
		$this->js_code_global = "";
		
		$this->property_update_code = "";
		
		$this->description = "";
		
		$this->databinding_updater = "";
		$this->pre_stmt_code = array();
		$this->pre_stmt_vars = array();
		$this->pre_stmt_count = 0;
		
		$this->param_parser_count = 0;
		
		
		$this->action_element_info = array();
		
		$this->component_types = array();
		
		$this->project_home = $project_home;
		
		$this->table_info = array();
		
		$this->load_module_info();
		
		$this->initial_js();
		
	}
	
	
	public function add_namespace($namespace)
	{
		$this->data_vars[$namespace] = array();
	}
	
	public function report_error($error_msg)
	{
		if( $this->error_msg == "" ) // the first one
		{
			$this->error_msg .= $this->description;
			echo $this->description;
		}
		$error_msg = "FATEL_ERROR:\n".
						$error_msg."\n<hr/>";
		$this->error_msg .= $error_msg;
		echo $error_msg;
	}
	
	public function get_errors()
	{
		return $this->error_msg;
	}
	
	/**
	 * generate symantic..
	 * @param $result_php_file result php file name
	 * @param $result_js_file result js file name
	 */	
	public function generate_symantic($result_dir, $result_php, $result_js, $result_decl_js)
	{
		$this->generate_data_vars();
		
		
		$this->copy_include_files($result_dir."../store/other/");
		
		$this->evaluate_databinding_database_expressions();

		$this->build_event_handler_js_code();
		$this->build_property_data_info();
		$this->init_js_vars_code();
		$this->php_actions_request_code();
		$this->databinding_updater_code();
		
		$this->generate_to_files($result_php, $result_js, $result_decl_js);
		
		
		return array("js"=> $this->js_includes, 
					"css"=> $this->css_includes);
		
		//print_r($this->databinding_vars);
	}
	
	public function generate_to_files($result_php, $result_js, $result_decl_js)
	{

		//print_r($this->databinding_vars);
		
		$js_content = "";
		
		$php_content = "<?php\n";
		
		$php_content .= "if(!isset(\$intergrated))\n";
		$php_content .= "{\n";
		$php_content .= "header('Content-Type: text/xml');\n";
		$php_content .= "header('Cache-control: no-cache');\n";
		$php_content .= "}\n\n";
		
		//print_r($this->js_action_vars);
		//print_r($this->php_action_vars);
		//first declare globals
		$js_content .= $this->js_code_global."\n";

		$result_js_file = fopen( $result_decl_js, "w+");
		fwrite($result_js_file, $js_content, strlen($js_content));
		fclose($result_js_file);
		
		//now write the next file..
		$js_content = "";
		$js_content .= "//first declare globals\n";
		$js_content .= "var SEMF = {};\n\n";
		$js_content .= "SEMF[\"page\"] = {};\n";
		$js_content .= "SEMF[\"sys\"] = {};\n\n";
		//$js_content .= "SEMF[\"dataModelFileName\"] = \"".$result_php."\";\n\n";
		//load action functions then..
		$keys = array_keys($this->js_action_vars);
		foreach ($keys as $id)
		{
			$actions = array_keys($this->js_action_vars[$id]);
			foreach ($actions as $action)
			{
				$data = $this->js_action_vars[$id][$action]["data"];
				$comment = "// Handling the $action of $id \n";
				$func_name = "SEMF.".$id."_".$action;
				$js_content .= $comment;
				$js_content .= $func_name. " = function()\n";
				$js_content .= "{\n";
				$js_content .= $data."\n";
				$js_content .= " SEMF.doUpdatePage();";
				$js_content .= "\n} // end of the function {$id}_$action\n\n";
			}
		}

		// function for on load
		$comment = "// Handling the common page onLoad function \n";
		$func_name = "SEMF.onLoad";
		$js_content .= $comment;
		$js_content .= $func_name. " = function()\n";
		$js_content .= "{\n";
		$js_content .= $this->js_code_on_load;
		$js_content .= "\n} // end of the function page onLoad\n\n";
		
		// loading include paths..
		$php_content .= $this->php_includes."\n";
		
		
		$php_content .= "
//load database information
\$db_info = get_database_info();\n\n";
	
		//connect to db..
		$php_content .= "\$link = mysql_connect(\$db_info['db_server'], 'root', \$db_info['db_password']); //right now we are hardcoded..\n";
		$php_content .= "if (!\$link) \n";
		$php_content .= "{\n";
		$php_content .= "   die('Could not connect: ' . mysql_error());\n";
		$php_content .= "}\n\n";
		$php_content .= "mysql_select_db(\$db_info[\"db_name\"]);\n\n";
		
		// js include path also shuld be set here.
		/*$php_content .= "echo <<<END_JS\n";
		$php_content .= "<!-- javascript includes -->\n";
		$php_content .= $this->js_includes."\n";
		$php_content .= "<!-- css includes -->\n";
		$php_content .= $this->css_includes."\n";
		$php_content .= "END_JS;\n"; */
		
		// first update the databind value if available..
		$php_content .= "\$property_name = \$_GET['propertyName'];\n";
		$php_content .= "\$data_id = \$_GET['dataId'];\n";
		$php_content .= "\$value = \$_GET['value'];\n";
		$php_content .= "\$add_remove = \$_GET['add_remove'];\n";
		$php_content .= "databinding_updater(\$property_name, \$data_id, \$value, \$add_remove);\n\n";
		
		// initializing php code with user variables..
		$php_content .= "\$funct_name = \$_GET['funct_name'];\n";
		$php_content .= "\$input_data = \$_GET;\n";

		// now load input_vars from the util function..
		$php_content .= "\$input_vars = load_input_vars_from_data(\$input_data);\n";
		$php_content .= "\$output_vars = NULL;\n";
		
		$php_content .= "//input some standard sys variables\n";
		$php_content .= "\$input_vars['sys']['link'] = \$link;\n";
		$php_content .= "\$input_vars['sys']['intergrated'] = \$intergrated;\n\n";
		
		$keys = array_keys($this->php_action_vars);
		foreach ($keys as $id)
		{
			$actions = array_keys($this->php_action_vars[$id]);
			foreach ($actions as $action)
			{
				
				if(strtolower($action) == "onload")
				{
					continue;//the will be called inside the page_onload
				}
				$func_name = $id."_".$action;
				$comment = "// if $func_name is called\n";
				$php_content .= $comment;
				$php_content .= "if (\$funct_name == \"$func_name\")\n";
	
				$php_content .= "{\n";
				$php_content .= "\$output_vars = ".$func_name. " (\$input_vars);\n";
				$php_content .= "}\n";
				//print_r($data);
			}
		}
		$php_content .= "\$just_loaded = false;\n";
		$php_content .= "if (!isset(\$funct_name) ||\$funct_name == \"\")\n";

		$php_content .= "{\n";
		$php_content .= "\$just_loaded = true;\n";
		$php_content .= "\$output_vars = page_on_load (\$input_vars);\n";
		$php_content .= "}\n";
		
		//close the connection before echo different..
		$php_content .= "\$output_vars['sys']['link'] = NULL;\n";
		
		
		// now finalize the work with util function..
		$php_content .= "\$php_return_data = echo_differences_of(\$input_vars, \$output_vars, \$just_loaded);\n";
		
		/*$php_content .= "if (isset(\$funct_name) && \$funct_name != \"\") //we need echo this here only not at startup..\n";

		$php_content .= "{\n";
		$php_content .= "echo \$return_data;\n";
		$php_content .= "}\n"; */
		$php_content .= "if(!\$intergrated)\n";
		$php_content .= "{\n";
		$php_content .= "echo \$php_return_data;\n";
		$php_content .= "}\n";
		$php_content .= "mysql_close(\$link);\n";
		
		// load functions for php..
		$keys = array_keys($this->php_action_vars);
		foreach ($keys as $id)
		{
			$actions = array_keys($this->php_action_vars[$id]);
			foreach ($actions as $action)
			{
				$data = $this->php_action_vars[$id][$action]["data"];
				$comment = "// Handling the $action of $id \n";
				$func_name = $id."_".$action;
				$php_content .= $comment;
				$php_content .= "function ".$func_name. " (\$args)\n";
				$php_content .= "{\n";
				$php_content .= $data;
				$php_content .= "return \$args;\n";
				$php_content .= "\n} // end of the function {$id}_$action\n\n";
				//print_r($data);
				
				if(strtolower($action) != "onload")
				{
					//the same function should be added on client side too
					$js_data = $this->php_action_vars[$id][$action]["js_data"];
					$comment = "// Handling the $action of $id (just for server request)\n";
					$func_name = "SEMF.".$id."_".$action;
					$js_content .= $comment;
					$js_content .= $func_name. " = function()\n";
					$js_content .= "{\n";
					$js_content .= $js_data;
					$js_content .= "\n} // end of the function {$id}_$action\n\n";
				}
			}
		}
		
		//function for on load in PHP
		$comment = "// Handling the common page_on_load function \n";
		$func_name = "page_on_load";
		$php_content .= $comment;
		$php_content .= "function ".$func_name. " (\$input_vars) \n";
		$php_content .= "{\n";
		$php_content .= $this->php_code_on_load_init_js;
		if( trim($this->php_code_on_load) == "")
		{
			$php_content .= "\$output_vars = \$input_vars; //now ouput will be the input;)\n";
		}
		$php_content .= $this->php_code_on_load;
		$php_content .= "\$output_vars[\"table\"] = \n";
		$php_content .= "       update_databound_properties(NULL, \$input_vars, 1);\n";
		$php_content .= "return \$output_vars;\n";
		$php_content .= "\n} // end of the function page_on_load\n\n";
		
		//starting to set the property_update_code..
		$php_content .= "// the following function will be called by util.php\n".
		                "// to update the values of databound properties\n";
		$php_content .= "function update_databound_properties(\$diff_vars, \$args, \$starter)\n";
		$php_content .= "{\n\n";
		$php_content .= "\$table_vars = \$args['table'];\n";
		$php_content .= $this->property_update_code."\n";
		$php_content .= "return \$table_vars;\n";
		$php_content .= "}\n";
		
		$php_content .= "//finally the function for databinding_updater..\n";
		$php_content .= $this->databinding_updater."\n";
		
						
		$php_content .= "?>\n";	
		
		$action_vars = $this->php_action_vars;
		
		//print_r($this->php_action_vars);
		//print_r($this->js_action_vars);
		
		//echo $action_vars['Page0']['onLoad']['data'];
		
		//echo $php_content;
		
		//saving it in a js file
		$result_js_file = fopen( $result_js, "w+");
		fwrite($result_js_file, $js_content, strlen($js_content));
		fclose($result_js_file);
		
		//saving it in a php file..
		$result_php_file = fopen( $result_php, "w+");
		fwrite($result_php_file, $php_content, strlen($php_content));
		fclose($result_php_file);
	}
	
	public function add_data_var($namespace, $var, $value)
	{
		if($this->data_vars[$namespace] == NULL)
		{
			$this->data_vars[$namespace] = array();
		}
		$this->data_vars[$namespace][$var] = $value;
	}
	
	public function generate_data_vars()
	{
		//generate namespaces
		$script_text = "";
		$namespaces = array_keys($this->data_vars);
		
		foreach($namespaces as $namespace)
		{
			$script_text .= $namespace;
			$script_text .= "=\n{\n";
			
			$variables = array_keys($this->data_vars[$namespace]);

			foreach($variables as $var)
			{
				$script_text .=  $var.":null,\n";
			}
			$script_text .= "_fa:null\n";
			$script_text .= "};\n";
		}
		$this->body_script .= $script_text;
		//echo $this->body_script;
	}
	
	public function load_data_vars()
	{
		$script_text = "";
		$script_text .= "//initializing databinding variables \n";
	}

	// this is to evaluate database declarations.. hooo	
	public function evaluate_declarations($parse_tree, $tokens)
	{
		//$parse_tree->print_this();
		$this->select_sql = "";
		$this->where_sql = "";
		$this->from_sql = "";
		
		$this->sql_script = "";
		
		//print_r($parse_tree);
		
		for($i = 1; $i <= count($parse_tree->childs); $i ++)
		{
			$stmt = $parse_tree->childs["stmt".$i];
			$this->evaluate_database_select($stmt, $tokens);
			break;
		}
	}
	
	/**
	 * this to evaluate select statments
	 * @param $stmt select statment parse tree
	 * @param $tokens associated tokens array
	 */
	public function evaluate_database_select($stmt, $tokens)
	{
		$this->current_table = "";
		$this->select_support_code = "";
		$this->from_sql = ""; //controversal..
		$this->where_sql = "";
		$this->select_sql = "";
		if ($stmt-> type == statement::$SELECT)
		{
			$from_stmt = $stmt-> childs["stmt1"];
			if( $from_stmt-> type != statement::$FROM)
			{
				$this->report_error("wrong symantic for SELECT");
				return -1;
			}
			//print_r($from_stmt);
			for( $i = 1; $i <= count($from_stmt->childs); $i ++ )
			{
				$from_decl = $from_stmt-> childs["stmt".$i];
				if( $from_decl-> type != statement::$FROM_DECL)
				{
					$this->report_error("wrong symantic for FROM");
					return -1;
				}
				if( $i > 1)
				{
					$this->from_sql .= ",";
				}
				if(trim($this->select_sql) != "")
				{
					$this->select_sql .= ",";
				}
				
				$table_name = $this->get_database_table_name($from_decl-> childs['expr1'], $tokens);
				$variable_name = $this->get_token_value($from_decl-> childs['expr2'], $tokens);
				
				// add things to from sql
				$this->from_sql .= $table_name;
				$this->from_sql .= " ".$variable_name." ";
				
				$this->current_table = $variable_name; //CHANGED
				
				// add things to select sql
				//echo $variable_name.":".$i;
				$this->select_sql .= $variable_name.".id ";
				
				$this->table_vars[$variable_name] = $table_name;
				
				if($this->php_table_inout_vars[$variable_name] == NULL)
				{
					$this->php_table_inout_vars[$variable_name] = "";
				}
				
			}
			$where_stmt = $stmt-> childs["stmt2"];
			if($where_stmt-> type != statement::$WHERE)
			{
				/*$this->report_error("wrong symantic for WHERE");
				return -1;*/
				$this-> where_sql = "";
			}
			else
			{
				$expression = $where_stmt->childs["expr1"];
				//print_r($expression);
				$this-> where_sql .= $this->parse_database_expression($expression, $tokens);
				
			}
		}
		//echo $this->where_sql."\n\n".$this->from_sql;
	}
	
	// currently only left hand side can have variables ..
	// This is to retrive data to properties..
	public function parse_data_dot_expression($expr, $tokens, $parent_table, $parent_table_var, $whs)
	{
		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		//print_r($this->table_vars);
		
		if($expr-> type == statement::$DOT)
		{
			//print_r($expr);
			if($parent_table == NULL) // this means the starting token is a data variable,
			{
			
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				
				
				if($child_var_expr->type == statement::$DATA_VAR) // this should be the first one..
				{
					$variable_name = $this->get_token_value($token, $tokens);
					$this->php_table_inout_vars[$variable_name] = "";
					
					//action should be taken if the variable name is already evaluated one..
					$table_name = $this->table_vars[$variable_name];
					
					
					$pos = strpos($this->from_sql, " ".$variable_name." ");
					if($pos == false)
					{
						$this->from_sql .= ", ".$table_name; //surely we should need comma.
						$this->from_sql .= " ".$variable_name." ";
						
						//some additional code should be added..
						$code = "";
						$code .= "\$data_table = array_keys(\$args['table']['".$variable_name."']); //just retrived the ids for \n";
		
						$code .= "\$query .=\"(\";\n";
						$code .= "\$total = count(\$data_table);\n";
						$code .= "if(\$total == 0)\n";
						$code .= "	\$query .= \"0\";\n";
						$code .= "\$i = 0;\n";
						$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
						$code .= "{\n";
						$code .= "	//complete the query dynamically..\n";
						$code .= "	\$query .= \"".$variable_name.
								 		".id = '\". \$data_value.\"'\";";
						$code .= "	\$i ++;\n";
						$code .= "	if(\$total != \$i)\n";
						$code .= "	{\n";
						$code .= "		\$query .= \" OR \";\n";
						$code .= "	}\n";
						$code .= "}\n";
						$code .= "\$query .=\")\";\n";	
						$this->select_support_code .= $code;
					}
					
					
					$parent_table = $table_name;
					$parent_table_var = $variable_name;
					$script_text = "";
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Check DOT expressions");
					return -1;
				}
				
			}
			else //not the starting one
			{
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				

				if($child_var_expr->type == statement::$CONSTANT) // this should be an intermediate one..
				{
					//remember this is not a table, it should just a field :(
					$field_name = $this->get_token_value($token, $tokens);
					$table_name = $this->get_table_name_from_field($parent_table, $field_name);
					
					
					// table name 
					$variable_name = $parent_table."__".$field_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= ", ".$table_name; //surely we should need comma.
					$this->from_sql .= " ".$variable_name." ";
				
					$is_array = $this->is_table_field_array($parent_table, $field_name);
					
					if( $is_array)
					{
						$inter_table = $parent_table."_".$field_name;
						$inter_table_variable = NULL;
						$i = 0;
						do{
							$inter_table_variable = $inter_table.$i;
							$i ++;
						}
						while($this->table_vars[$inter_table_variable] != NULL);
						$this->table_vars[$inter_table_variable] = $inter_table;
						
						$this->from_sql .= ", ".$inter_table." ".$inter_table_variable;
						
						if($whs == "lhs")
						{
							$script_text .= $parent_table_var.".id = ". $inter_table_variable.".id and ";
						}
						elseif($whs == "rhs")
						{
							$script_text = " and ".$parent_table_var.".id = ".
									 $inter_table_variable.".id ".$script_text;
						}
						$parent_table_var = $inter_table_variable;
						$parent_table = $inter_table;
								//$inter_table_varible.".".$field_name." = ".$variable_name.".id and ";
					}
					//else
					{
						// the first value is compulsoraly a table name..
						if($whs == "lhs")
						{
							$script_text .= $parent_table_var.".".$field_name." = ". 
								$variable_name.".id and ";
						}
						elseif($whs == "rhs")
						{
							$script_text = " and ".$parent_table_var.".".$field_name." = ". 
								$variable_name.".id ".$script_text;
						}
					}
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Revise DOT expressions");
					return -1;
				}
			}
			// here table_name referes to the first table_name
			// variable_name referes to the second table_name..
				
			//checking the second expression
			$child_expr = $expr-> childs["expr2"];
			$child_dot_or_var_expr = $child_expr-> childs["expr1"];
			$token = $child_dot_or_var_expr-> childs["expr1"];
			
			if( $child_dot_or_var_expr->type == statement::$CONSTANT)
			{
				//this means the everything is over..
				$second_field_name = $this->get_token_value($token, $tokens);
				//echo "$second_field_name\n";
				$second_table_name = $this->get_table_name_from_field($table_name, $second_field_name);
					
				$is_array = $this->is_table_field_array($table_name, $second_field_name);
			
				if($is_array)
				{
					$inter_table = $table_name."_".$second_field_name;
					$inter_table_variable = NULL;
					$i = 0;
					do{
						$inter_table_variable = $inter_table.$i;
						$i ++;
					}
					while($this->table_vars[$inter_table_variable] != NULL);
					$this->table_vars[$inter_table_variable] = $inter_table;
					
					$this->from_sql .= " , ".$inter_table." ".$inter_table_variable;
					
					if($whs == "lhs")
					{
						$script_text .= $variable_name.".id = ". $inter_table_variable.".id and ";
					}
					elseif($whs == "rhs")
					{
						$script_text = " and ".$variable_name.".id = ". $inter_table_variable.".id ".$script_text;
					}
							//$inter_table_variable.".".$second_field_name." = ".$variable_name.".id and ";
					//$second_table_name = $this->get_table_name_from_field($inter_table, $second_field_name);
					
					//$second field name + $second table name doesnt change
					$variable_name = $inter_table_variable;
				}	
				
				if( $second_table_name == -1 ) // this means that the field is not a table
				{
					if($whs == "lhs")
					{
						$script_text .= $variable_name.".".$second_field_name;
					}
					elseif($whs == "rhs")
					{
						$script_text = $variable_name.".".$second_field_name.$script_text;
					}
				}
				else // it is a table. we have to go more..:(
				{
					$second_variable_name = $second_table_name."__".$second_field_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= ", ".$second_table_name; //surely we should need comma.
					$this->from_sql .= " ".$second_variable_name." ";
					
					if($whs == "lhs")
					{
						$script_text .= $variable_name.".".$second_field_name."=". //now this is an id
								   $second_variable_name.".id and ".
								   $second_variable_name.".id ";
					}
					elseif($whs == "rhs")
					{
						$script_text = $second_variable_name.".id and ".
										$variable_name.".".$second_field_name."=". //now this is an id
								   		$second_variable_name.".id".$script_text;
					}
				}
				
			}
			elseif($child_dot_or_var_expr->type == statement::$DOT)
			{
				//more to go.
				$returned_text = 
						$this->parse_data_dot_expression($child_dot_or_var_expr, $tokens,
										$table_name, $variable_name, $whs);
				if($retuned_text == -1)
				{
					return -1;
				}
				if($whs == "lhs")
				{
					$script_text .= "  ".$returned_text;
				}
				elseif($whs == "rhs")
				{
					$script_text = $returned_text."  ".$script_text;
				}
			}
			else
			{
				$this->report_error(
				   "wrong symantics at the end of the dot expression around WHERE");
				return -1;
			}
			
						
			
		}
		
		return $script_text;
		
	}
	
	public function get_table_name_from_field($table_name, $field_name)
	{
		//print_r($this->table_info);
		if(!is_array($this->table_info[$table_name][$field_name]))
		{
			$this->report_error("The field ${field_name} is not in table ${table_name}");
			return -1;
		}
		$table_name = $this->table_info[$table_name][$field_name]["table"];
		if($table_name == NULL)
		{
			return -1;
		}
		return $table_name;
	}
	
	
	public function is_table_field_array($table_name, $field_name)
	{
		$isarray = $this->table_info[$table_name][$field_name]["array"];
		if($isarray == NULL)
		{
			return false;
		}
		return true;
	}
	
	public function parse_database_expression_rhs($parse_tree, $tokens)
	{
		if($parse_tree-> type == statement::$DOT)
		{
			//print_r($parse_tree);
			$script_text = $this->parse_data_dot_expression($parse_tree, $tokens, NULL, NULL, "rhs");
		}
		else
		{
			$script_text = $this->parse_database_expression($parse_tree, $tokens);
		}
		return $script_text;
	}
	
	public function parse_database_expression($parse_tree, $tokens)
	{
		
		$script_text = "";
		if($parse_tree-> type == statement::$EXPR)
		{
			$script_text = "(".$this->parse_database_expression($parse_tree->childs['expr1'], $tokens).")";
		}
		else if($parse_tree-> type == statement::$DOT)
		{
			//print_r($parse_tree);
			$script_text = $this->parse_data_dot_expression($parse_tree, $tokens, NULL, NULL, "lhs");
		}
		elseif($parse_tree->type == statement::$EQUAL ||
		 $parse_tree->type == statement::$EQUILITY)
		{
			$lhs = $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens);
			$rhs = $this->parse_database_expression_rhs($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
			$script_text .= $lhs." = ".$rhs;
		}
		elseif($parse_tree->type == statement::$NOT_EQUILITY)
		{
			$lhs = $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens);
			$rhs = $this->parse_database_expression_rhs($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
			$script_text .= $lhs." <> ".$rhs;
		}
		elseif($parse_tree->type == statement::$LESS_THAN)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " < ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$GREATER_THAN)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " > ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		//dot should be handled different way
		/*elseif($parse_tree->type == statement::$DOT)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " . ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		} */
		elseif($parse_tree->type == statement::$ADD)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " + ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SUB)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " - ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$MUL)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " = ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " * ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$ADD_EQUAL)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " += ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SUB_EQUAL)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " -= ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$MUL_EQUAL)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " *= ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV_EQUAL)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " /= ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}elseif($parse_tree->type == statement::$OR)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " OR ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$AND)
		{
			$script_text .= $this->parse_database_expression($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " AND ".
							$this->parse_database_expression($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$VARIABLE) // these are page variables
		{
			$var_name = $this->get_token_value($parse_tree, $tokens);
			$script_text .= "'{\$args['page']['".$var_name."']}'";
			$this->page_php_vars[$var_name] = "";
			$this->php_inout_vars[$var_name] = "";
		}
		elseif($parse_tree->type == statement::$DATA_VAR) // these are page variables
		{
			$var_name = $this->get_token_value($parse_tree, $tokens);
			$script_text .= $var_name.".id ";
			
			$variable_name = $var_name;
			$table_name = $this->table_vars[$variable_name];
					
			$pos = strpos($this->from_sql, " ".$variable_name." ");
			if($pos == false)
			{
				$this->from_sql .= ", ".$table_name; //surely we should need comma.
				$this->from_sql .= " ".$variable_name." ";
				
				//some additional code should be added..
				$code = "";
				$code .= "\$data_table = array_keys(\$args['table']['".$variable_name."']); //just retrived the ids for \n";

				$code .= "\$query .=\"(\";\n";
				$code .= "\$total = count(\$data_table);\n";
				$code .= "if(\$total == 0)\n";
				$code .= "	\$query .= \"0\";\n";
				$code .= "\$i = 0;\n";
				$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
				$code .= "{\n";
				$code .= "	//complete the query dynamically..\n";
				$code .= "	\$query .= \"".$variable_name.
								".id = '\". \$data_value.\"'\";";
				$code .= "	\$i ++;\n";
				$code .= "	if(\$total != \$i)\n";
				$code .= "	{\n";
				$code .= "		\$query .= \" OR \";\n";
				$code .= "	}\n";
				$code .= "}\n";
				$code .= "\$query .=\")\";\n";	
				$this->select_support_code .= $code;
			}
					
		}
		elseif($parse_tree->type == statement::$CONSTANT) // these are page variables
		{
			$script_text .= "'".$this->get_token_value($parse_tree, $tokens)."'";
		}
		elseif($parse_tree->type == statement::$NUMBER) // these are page variables
		{
			$script_text .= " ".$this->get_token_value($parse_tree, $tokens)." ";
		}
		elseif($parse_tree->type == statement::$SYS_VAR) // these are page variables
		{
			$sys_var =  $this->get_token_value($parse_tree, $tokens);
			// the sys_var should be checked within a switch sooner or later:(
			$script_text = "";
		}
		
		//now parse the tokens
		
		elseif($parse_tree->type == statement::$TOKEN)
		{
			for($i = $parse_tree->start; $i <= $parse_tree->end; $i ++)
			{
				$script_text .= $tokens[$i]->value;
			}
		}
		return $script_text;
	}
	
	public function get_database_table_name($stmt, $tokens)
	{
		if($stmt-> type != statement::$DOT)
		{
			$this->report_error("Incomplete database object name. Module name missing");
			return -1;
		}
		$child0 = $this->get_token_value($stmt->childs['expr1'], $tokens);
		$child1 = $this->get_token_value($stmt->childs['expr2'], $tokens);
		
		if($child0 == "" || $child0 == NULL )
		{
			$this->report_error("Incomplete database object name. Module name missing");
			return -1;
		}
		else if($child1 == "" || $child1 == NULL )
		{
			$this->report_error("Incomplete database object name. Object name missing");
			return -1;
		}
		
		return $child0."_".$child1;
	}
	
	public function get_token_value($stmt, $tokens)
	{
		if($stmt-> type == statement::$STATEMENT ||
		    $stmt-> type == statement::$EXPR ||
		    $stmt-> type == statement::$VARIABLE ||
		    $stmt-> type == statement::$CONSTANT ||
		    $stmt-> type == statement::$NUMBER ||
		    $stmt-> type == statement::$DATA_VAR ||
		    $stmt-> type == statement::$SYS_VAR)
		{
			$child_stmt = $stmt->childs['stmt0'];
			if($child_stmt == NULL)
			{
				$child_stmt = $stmt->childs['expr0'];
			}
			if($child_stmt == NULL)
			{
				$child_stmt = $stmt->childs['expr1'];
			}
			if($child_stmt == NULL)
			{
				$child_stmt = $stmt->childs['stmt1'];
			}
			return $this->get_token_value($child_stmt, $tokens);
		}
		elseif($stmt->type == statement::$TOKEN)
		{
			return $tokens[$stmt-> start]->value;
		}
		else
		{
			return NULL;
		}
	}
	
		
	// currently only left hand side can have variables ..
	/**
	 * @param $rhs_data if the right hand side is a data variable the data variable
	 *					Otherwise NULL
	 */
	public function parse_data_update_dot_expression($expr, $tokens, $parent_table, $parent_table_var, $rhs_data)
	{

		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		//print_r($this->table_vars);
		
		if($expr-> type == statement::$DOT)
		{
			//print_r($expr);
			if($parent_table == NULL) // this means the starting token is a data variable,
			{
			
				$this->update_where_sql = NULL;
				
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				
				if($child_var_expr->type == statement::$DATA_VAR) // this should be the first one..
				{
					$variable_name = $this->get_token_value($token, $tokens);
					
					//action should be taken if the variable name is already evaluated one..
					$table_name = $this->table_vars[$variable_name];
					
					if($table_name == NULL )
					{
						$table_name = "anonymous_table";
						$this->report_error("Data variable with unspecified Table :".$variable_name);
						return -1;
					}
			
					$this->php_table_inout_vars[$variable_name] = "";
					
					// this is to retireve the requried values for checking all
					// the available id values from a loop.
					 $this->addition_sql_lhs = $variable_name.".id";
					 $this->addition_sql_rhs = $variable_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= $table_name; //surely this is the first one.
					$this->from_sql .= " ".$variable_name." ";
					
					$parent_table = $table_name;
					$parent_table_var = $variable_name;
					$script_text = "";
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Check DOT expressions");
					return -1;
				}
				
			}
			else //not the starting one
			{
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				

				if($child_var_expr->type == statement::$CONSTANT) // this should be an intermediate one..
				{
					//remember this is not a table, it should just a field :(
					$field_name = $this->get_token_value($token, $tokens);
					$table_name = $this->get_table_name_from_field($parent_table, $field_name);
					
					
					// table name 
					$variable_name = $parent_table."__".$field_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= ", ".$table_name; //surely we should need comma.
					$this->from_sql .= " ".$variable_name." ";
				
					$is_array = $this->is_table_field_array($parent_table, $field_name);
					
					if( $is_array)
					{
						$inter_table = $parent_table."_".$field_name;
						$inter_table_variable = NULL;
						$i = 0;
						do{
							$inter_table_variable = $inter_table.$i;
							$i ++;
						}
						while($this->table_vars[$inter_table_variable] != NULL);
						$this->table_vars[$inter_table_variable] = $inter_table;
						
						$this->from_sql .= ", ".$inter_table." ".$inter_table_variable;
						
						$script_text .= $parent_table_var.".id = ". $inter_table_variable.".id and ";
								//$inter_table_varible.".".$field_name." = ".$variable_name.".id and ";
						$parent_table_var = $inter_table_variable;
						$parent_table = $inter_table;
					}
					//else
					{
						// the first value is compulsoraly a table name..
						$script_text .= $parent_table_var.".".$field_name." = ". 
								$variable_name.".id and ";
					}
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Revise DOT expressions");
					return -1;
				}
			}
			// here table_name referes to the first table_name
			// variable_name referes to the second table_name..
				
			//checking the second expression
			$child_expr = $expr-> childs["expr2"];
			$child_dot_or_var_expr = $child_expr-> childs["expr1"];
			$token = $child_dot_or_var_expr-> childs["expr1"];
			
			if( $child_dot_or_var_expr->type == statement::$CONSTANT) //this is the end line..
			{
				//this means the everything is over..
				
				$second_field_name = $this->get_token_value($token, $tokens);
				//echo "$second_field_name\n";
				
				$second_table_name = $this->get_table_name_from_field($table_name, $second_field_name);
			
				$is_array = $this->is_table_field_array($table_name, $second_field_name);
			
				if($is_array)
				{
					//first verify it we are capturing the last one out..
					$this->update_where_sql = $script_text." ";
					
					
					$inter_table = $table_name."_".$second_field_name;
					$inter_table_variable = NULL;
					$i = 0;
					do{
						$inter_table_variable = $inter_table.$i;
						$i ++;
					}
					while($this->table_vars[$inter_table_variable] != NULL);
					$this->table_vars[$inter_table_variable] = $inter_table;
					
					$this->from_sql .= " , ".$inter_table." ".$inter_table_variable;
						
					$script_text .= $variable_name.".id = ". $inter_table_variable.".id and ";
					$this->update_select_sql = $variable_name.".id";
					$this->update_array_table = $inter_table."(id, ".$second_field_name.")";
					$this->update_array_table_entry = $inter_table;
					$this->update_field_name = $second_field_name;
							//$inter_table_variable.".".$second_field_name." = ".$variable_name.".id and ";
					//$second_table_name = $this->get_table_name_from_field($inter_table, $second_field_name);
					
					//$second field name + $second table name doesnt change
					$variable_name = $inter_table_variable;
				}	
							
				if($second_table_name == -1) // this means that the field is not a table
				{
					$script_text .= ""; //just for remove the unnecessory and..
					$this->update_sql .= $variable_name.".".$second_field_name;
				}
				
				else // it is a table. we have to go more..:(
				{
					if( $rhs_data == NULL)
					{
						$second_variable_name = $second_table_name."__".$second_field_name;
						// add things to from sql registering the variable name
						// associated with the table name..
						
						$this->from_sql .= ", ".$second_table_name; //surely we should need comma.
						$this->from_sql .= " ".$second_variable_name." ";
						$script_text .= $variable_name.".".$second_field_name."=". //now this is an id
									   $second_variable_name.".id ";
									   
						$this->update_sql .= $second_variable_name.".id ";
					}
					else //completely different senario..
					{
						//no second variable exists actually..
						$rhs_table = $this->table_vars[$rhs_data];
						if( $rhs_table != $second_table_name)
						{
							$this->report_error(
							   "Type Mismatch in assigning. Check types again..");
							return -1;
						}
						//but the first one will be updated..
						$this->update_sql .= $variable_name.".".$second_field_name;
						
					}
				}
				
			}
			elseif($child_dot_or_var_expr->type == statement::$DOT)
			{
				//more to go.
				$returned_text = 
						$this->parse_data_update_dot_expression($child_dot_or_var_expr,
								 $tokens, $table_name, $variable_name, $rhs_data);
				if($retuned_text == -1)
				{
					return -1;
				}
				$script_text .= "  ".$returned_text;
			}
			else
			{
				$this->report_error(
				   "wrong symantics at the end of the dot expression around WHERE");
				return -1;
			}
			
		}
		
		return $script_text;
		
	}
	
	/**
	 * algorithm for the delete operation.
	 * @param $expr delete expression parse tree..
	 * @param $tokens associated token array
	 */
	public function parse_data_delete_expression($expr, $tokens)
	{
		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		//print_r($expr);
		
		if($expr-> type == statement::$DELETE)
		{
			$child_expr = $expr-> childs["expr1"];
			$child_var_expr = $expr-> childs["expr1"];
			$token = $child_var_expr-> childs["expr1"];
			if( $child_var_expr->type != statement::$DATA_VAR)
			{
				$this->report_error("wrong symantics for DELETE. DELETE should be followed by data variable..");
				return -1;
			}
			$token_value = $this->get_token_value($token, $tokens);
			$this->current_table = $token_value;
			
			$this->php_table_inout_vars[$this->current_table] = "";
			
			if( $this->table_vars[$this->current_table] == NULL ) //undeclared table..
			{
				$this->report_error("privously undeclared table cannot be deleted:(");
				return -1;
			}
		}
	}
		
	/**
	 * algorithm to handle declare symantic handling..
	 * @param $expr declare expression parse tree..
	 * @param $tokens associated token array
	 */
	public function parse_data_declare_expression($expr, $tokens)
	{
		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		//print_r($expr);
		
		if($expr-> type == statement::$DECL)
		{
			$child_var_expr = $expr-> childs["expr1"];
			$token = $child_var_expr-> childs["expr1"];
			if( $child_var_expr->type != statement::$DATA_VAR)
			{
				$this->report_error("wrong symantics for DECL/ DECLARWE. it should be followed by data variable..");
				return -1;
			}
			$token_value = $this->get_token_value($token, $tokens);
			$this->current_table = $token_value;
			
			$table_name_expr = $expr-> childs["expr2"];
			if( $table_name_expr->type != statement::$DOT)
			{
				$this->report_error("wrong symantics for DECL/ DECLARWE. RHS should be a table name (DOT expression)..");
				return -1;
			}
			
			$table_name = $this->get_database_table_name($table_name_expr, $tokens);
			
			$this->table_vars[$this->current_table] = $table_name;
			
			$this->php_table_inout_vars[$this->current_table] = "";
		}
	}
		
	/**
	 * algorithm to handle cast symantic handling..
	 * @param $expr cast expression parse tree..
	 * @param $tokens associated token array
	 */
	public function parse_data_cast_expression($expr, $tokens)
	{
		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		//print_r($expr);
		
		if($expr-> type == statement::$CAST)
		{
			$child_var_expr = $expr-> childs["expr1"];
			$token = $child_var_expr-> childs["expr1"];
			if( $child_var_expr->type != statement::$DATA_VAR)
			{
				$this->report_error("wrong symantics for DECL/ DECLARWE. it should be followed by data variable..");
				return -1;
			}
			$token_value = $this->get_token_value($token, $tokens);
			$this->current_table = $token_value;
			
			$table_name_expr = $expr-> childs["expr2"];
			if( $table_name_expr->type != statement::$DOT)
			{
				$this->report_error("wrong symantics for DECL/ DECLARWE. RHS should be a table name (DOT expression)..");
				return -1;
			}
			$table_name = $this->get_database_table_name($table_name_expr, $tokens);
			
			$this->table_vars[$this->current_table] = $table_name;
			
			$this->php_table_inout_vars[$this->current_table] = "";
			
			$child_var_expr = $expr-> childs["expr3"];
			$token = $child_var_expr-> childs["expr1"];
			if( $child_var_expr->type != statement::$DATA_VAR)
			{
				$this->report_error("wrong symantics for DECL/ DECLARWE. it should be followed by data variable..");
				return -1;
			}
			$old_token_value = $this->get_token_value($token, $tokens);
			return $old_token_value;
		}
		return NULL;
	}
	
	/**
	 * parse table chain for retrival of data
	 * (currently only left hand side can have variables ..)
	 * @param $expr delete expression parse tree..
	 * @param $tokens associated token array
	 */
	public function parse_data_retrieve_dot_expression($expr, $tokens, $parent_table, $parent_table_var)
	{
		$script_text = "";
		$table_name = "";
		$variable_name = "";
		
		$token_name = "";
		
		//print_r($this->table_vars);
		
		if($expr-> type == statement::$DOT)
		{
			//print_r($expr);
			if($parent_table == NULL) // this means the starting token is a data variable,
			{
			
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				
				if($child_var_expr->type == statement::$DATA_VAR) // this should be the first one..
				{
					$variable_name = $this->get_token_value($token, $tokens);
					$this->php_table_inout_vars[$variable_name] = "";
					
					//action should be taken if the variable name is already evaluated one..
					$table_name = $this->table_vars[$variable_name];
					
					if($table_name == NULL )
					{
						$table_name = "anonymous_table";
						$this->report_error("Data variable with unspecified Table :".$variable_name);
						return -1;
					}
					
					// this is to retireve the requried values for checking all
					// the available id values from a loop.
					 $this->addition_sql_lhs = $variable_name.".id";
					 $this->addition_sql_rhs = $variable_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= $table_name; //surely this is the first one.
					$this->from_sql .= " ".$variable_name." ";
					
					// we want to retrieve the corrosponding id as well,
					$this->select_sql .= $variable_name.".id ";
					
					$parent_table = $table_name;
					$parent_table_var = $variable_name;
					$script_text = "";
					
					// put the starting variable in to the stack.
					$token_name = $variable_name;
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Check DOT expressions");
					return -1;
				}
				
			}
			else //not the starting one
			{
				$child_expr = $expr-> childs["expr1"];
				$child_var_expr = $child_expr-> childs["expr1"];
				$token = $child_var_expr-> childs["expr1"];
				

				if($child_var_expr->type == statement::$CONSTANT) // this should be an intermediate one..
				{
					//remember this is not a table, it should just a field :(
					$field_name = $this->get_token_value($token, $tokens);
					$table_name = $this->get_table_name_from_field($parent_table, $field_name);

					
					
					// table name 
					$variable_name = $parent_table."__".$field_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= ", ".$table_name; //surely we should need comma.
					$this->from_sql .= " ".$variable_name." ";
				
					$is_array = $this->is_table_field_array($parent_table, $field_name);
					
					if( $is_array)
					{
						$inter_table = $parent_table."_".$field_name;
						$inter_table_variable = NULL;
						$i = 0;
						do{
							$inter_table_variable = $inter_table.$i;
							$i ++;
						}
						while($this->table_vars[$inter_table_variable] != NULL);
						$this->table_vars[$inter_table_variable] = $inter_table;
						
						$this->from_sql .= ", ".$inter_table." ".$inter_table_variable;
						
						$script_text .= $parent_table_var.".id = ". $inter_table_variable.".id and ";
						$parent_table_var = $inter_table_variable;
						$parent_table = $inter_table;
								//$inter_table_varible.".".$field_name." = ".$variable_name.".id and ";
					}
					//else
					{
						// the first value is compulsoraly a table name..
						$script_text .= $parent_table_var.".".$field_name." = ". 
									$variable_name.".id and ";
						
					}
					$token_name = $field_name;
				}
				else
				{
					// I cant think of something else..
					$this->report_error("wrong symantics for WHERE. Revise DOT expressions");
					return -1;
				}
			}
			// here table_name referes to the first table_name
			// variable_name referes to the second table_name..
				
			//checking the second expression
			$child_expr = $expr-> childs["expr2"];
			$child_dot_or_var_expr = $child_expr-> childs["expr1"];
			$token = $child_dot_or_var_expr-> childs["expr1"];
			
			if( $child_dot_or_var_expr->type == statement::$CONSTANT)
			{
				//this means the everything is over..
				$second_field_name = $this->get_token_value($token, $tokens);
				//echo "$second_field_name\n";
				$second_table_name = $this->get_table_name_from_field($table_name, $second_field_name);
				
				$is_array = $this->is_table_field_array($table_name, $second_field_name);
			
				if($is_array)
				{
					$inter_table = $table_name."_".$second_field_name;
					$inter_table_variable = NULL;
					$i = 0;
					do{
						$inter_table_variable = $inter_table.$i;
						$i ++;
					}
					while($this->table_vars[$inter_table_variable] != NULL);
					$this->table_vars[$inter_table_variable] = $inter_table;
					
					$this->from_sql .= " , ".$inter_table." ".$inter_table_variable;
						
					$script_text .= $variable_name.".id = ". $inter_table_variable.".id and ";
							//$inter_table_variable.".".$second_field_name." = ".$variable_name.".id and ";
					//$second_table_name = $this->get_table_name_from_field($inter_table, $second_field_name);
					
					//$second field name + $second table name doesnt change
					$variable_name = $inter_table_variable;
				}	
				
				if( $second_table_name == -1 ) // this means that the field is not a table
				{
					$script_text .= ""; //just for remove the unnecessory and..
					if( $this->select_sql != "")
					{
						$this->select_sql.= " , ";
					}
					$this->select_sql .= $variable_name.".".$second_field_name;
					
					$this->databinding_stack[$token_name] = array();
					$this->databinding_stack[$token_name][$second_field_name] = 1;
				}
				else // it is a table. we have to go more..:(
				{
					$second_variable_name = $second_table_name."__".$second_field_name;
					
					// add things to from sql registering the variable name
					// associated with the table name..
					
					$this->from_sql .= ", ".$second_table_name; //surely we should need comma.
					$this->from_sql .= " ".$second_variable_name." ";
					
					$script_text .= $variable_name.".".$second_field_name."=". //now this is an id
								   $second_variable_name.".id ";
							
					if( $this->select_sql != "")
					{
						$this->select_sql.= " , ";
					}	   
					$this->select_sql .= $second_variable_name.".id ";
					
					$this->databinding_stack[$token_name] = array();
					$this->databinding_stack[$token_name][$second_field_name] = 1; //just check this again in any problem..
				}
				
			}
			elseif($child_dot_or_var_expr->type == statement::$DOT)
			{
				//more to go.
				$this->select_sql .= "";
				$returned_text = 
						$this->parse_data_retrieve_dot_expression($child_dot_or_var_expr, $tokens,
										$table_name, $variable_name);
										
				$temp_databinding_stack = $this->databinding_stack;
				$this->databinding_stack = array();
				$this->databinding_stack[$token_name] = $temp_databinding_stack;
				
				if($retuned_text == -1)
				{
					return -1;
				}
				$script_text .= "  ".$returned_text;
			}
			else
			{
				$this->report_error(
				   "wrong symantics at the end of the dot expression around WHERE");
				return -1;
			}
			
		}
		
		return $script_text;
		
	}
	
	/**
	 * this is symatic handler for databinding properties..
	 * @param $parse_tree  expression parse tree..
	 * @param $tokens associated token array
	 * @param $id id of the component
	 * @param $property name of the property..
	 */
	public function evaluate_databinding_statement($parse_tree, $tokens,
	 					 $id, $property, $description)
	{
		//$parse_tree->print_this();
		
		//print_r($parse_tree);
		$this->error_msg  = "";
		$this->description = $description;
		if($this-> databinding_vars[$id] == NULL)
		{
			$this-> databinding_vars[$id] = array();
		}
		$this-> databinding_vars[$id][$property] = array();
		for($i = 1; $i <= count($parse_tree->childs); $i ++)
		{
			$this->select_sql = "";
			$this->where_sql = "";
			$this->from_sql = "";
			$this->update_sql = "";
			$this->sql_script = "";
			
			$this->addition_sql_lhs = "";
			$this->addition_sql_rhs = "";
			
			$stmt = $parse_tree->childs["stmt".$i];
			if( $stmt == NULL)
			{
				$stmt = $parse_tree->childs["expr".$i];
			}
			$data = $this->evaluate_databinding_values($stmt, $tokens);
			
			//print_r($data);
			
			$this-> databinding_vars[$id][$property] = $data;
			// thre should be no duplicate values..
			break;
		}
		//print_r($this-> databinding_vars);
	}
	
	/**
	 * evaluation of the parse tree for individual property..
	 * @param $parse_tree  expression parse tree..
	 * @param $tokens associated token array
	 */
	public function evaluate_databinding_values($parse_tree, $tokens)
	{
		if($parse_tree->type == statement::$DOT)
		{
			$this->databinding_stack = array(); // would be using throughout the parse_data_retrieve
			
			$this->select_sql = "";
			
			$this->where_sql = 
			   $this->parse_data_retrieve_dot_expression($parse_tree, $tokens, NULL, NULL);
			$the_sql = $this->build_select_sql_string(); // compulsorily the select statement..
			$tailer_sql = "";
			if($this->where_sql == "")
			{
				$tailer_sql .= " WHERE "; // we need the where to this only..
			}
			$addition_lhs = $this->addition_sql_lhs;
			$addition_rhs = $this->addition_sql_rhs;
		
			/* going for property set part */
			$this->where_sql = $this->from_sql = $this->update_sql = "";
			$this->where_sql = 
				$this->parse_data_update_dot_expression($parse_tree, $tokens, NULL, NULL, NULL);
				
			$the_update_sql = "UPDATE ".$this->from_sql;
			$the_update_sql.= " SET ".$this->update_sql." = ('{\$value}')";
			
			$the_update_sql .= " WHERE ".$this->where_sql;
			$the_update_sql .= $addition_lhs."='{\$data_id}'";

			//now we are going to act little different..
			$array_on_update = array();
			if($this->update_where_sql != NULL) //if it is an array to update..
			{
				$array_on_update["update_array"] = 1;
				$array_on_update["update_where"] = $this->update_where_sql;
				$array_on_update["update_select"] = $this->update_select_sql;
				$array_on_update["update_from"] = $this->from_sql;
				$array_on_update["update_table"] = $this->update_array_table;
				$array_on_update["update_table_entry"] = $this->update_array_table_entry;
				$array_on_update["update_field_name"] = $this->update_field_name;
			}
								
			return array_merge(
					$array_on_update,
					array(
			            "data_query"=> $the_sql,
						"data_query_tailer"=> $tailer_sql,
			            "data_update"=> $the_update_sql,
						"stack"=> $this->databinding_stack,
						"addition_lhs"=> $addition_lhs,
						"addition_rhs"=> $addition_rhs,
						"type"=>"data"));
		}
		else if($parse_tree->type == statement::$CONSTANT ||
				$parse_tree->type == statement::$NUMBER )
		{
			$const = $this->get_token_value($parse_tree, $tokens);
			return array(
			            "value"=> $const,
						"type"=>"const");
			
		}
		else if($parse_tree->type == statement::$VARIABLE)
		{
			$var = $this->get_token_value($parse_tree, $tokens);
			return array(
			            "value"=> $var,
						"type"=>"var");
		}
		else if($parse_tree->type == statement::$SYS_VAR)
		{
			$var = $this->get_token_value($parse_tree, $tokens);
			return array(
			            "value"=> $var,
						"type"=>"sysvar");
		}
		else
		{
			echo $parse_tree->type."\n";
			$this->report_error(
			   "wrong symantics for the databinding properties");
			return -1;
		}
	}
	
	/**
	 * build sql string for select
	 */
	private function build_select_sql_string()
	{
		$query = "SELECT ".$this->select_sql." FROM ".$this->from_sql;
		if($this->where_sql != "")
		{
			$query .= " WHERE ";
			$query .= $this->where_sql;
		}
		return $query;
	}
	
	
	// this is a big function here:|
	public function evaluate_action_statement($parse_tree, $tokens,
									 $id, $action, $description)
	{
		
		if($parse_tree == null || count($parse_tree->childs) == 0)
		{
			return;
		}

		$this->error_msg = "";
		$this->description = $description;
		
		
		$data = "";
		$js_actions = array();
		$php_actions = array();
		$this->js_possible = true;
		for($i = 1; $i <= count($parse_tree->childs); $i ++)
		{
			$this->select_sql = "";
			$this->where_sql = "";
			$this->from_sql = "";
			$this->update_sql = "";
			$this->sql_script = "";
			
			$this->addition_sql_lhs = "";
			$this->addition_sql_rhs = "";
			$this->js_possible = true;
			
			// some special is done to onload only..
			if( strtolower($action) == "onload" )
			{
				$this->js_possible = false;
				break;
			}
			
			$stmt = $parse_tree->childs["stmt".$i];
			if( $stmt == NULL)
			{
				$stmt = $parse_tree->childs["expr".$i];
			}
			//print_r($stmt);
			$data .= $this->evaluate_action_for_js($stmt, $tokens);
			
			
			if(!$this->js_possible) //javascript cant handle this..
			{
				//$data = $this->evaluate_action_for_php($stmt, $tokens);
				break;
			}
						
			// thre should be no duplicate va
		}
		$js_actions = $data;
		
			
		if(!$this->js_possible) //javascript cant handle this..
		{	
			$data = "";
			$this->php_inout_vars = array();
			$this->php_table_inout_vars = array();		
			//try things at php side
			for($i = 1; $i <= count($parse_tree->childs); $i ++)
			{
				$this->select_sql = "";
				$this->where_sql = "";
				$this->from_sql = "";
				$this->update_sql = "";
				$this->sql_script = "";
				
				$this->addition_sql_lhs = "";
				$this->addition_sql_rhs = "";
				$this->js_possible = true;
				
				$stmt = $parse_tree->childs["stmt".$i];
				if( $stmt == NULL)
				{
					$stmt = $parse_tree->childs["expr".$i];
				}
				//print_r($stmt);
				
				$data .= $this->evaluate_action_for_php($stmt, $tokens);
				
				//print_r($data);
				
				// thre should be no duplicate va
			}
			$php_actions = $data;
			//after all..
			if($this-> php_action_vars[$id] == NULL)
			{
				$this-> php_action_vars[$id] = array();
			}
			$this-> php_action_vars[$id][$action] = array();
			$this-> php_action_vars[$id][$action]["data"] = $php_actions;
			$this-> php_action_vars[$id][$action]["inout"] = $this->php_inout_vars;
			$this-> php_action_vars[$id][$action]["table_inout"] = $this->php_table_inout_vars;
		}
		else
		{
			//javascript can handle this
			if($this-> js_action_vars[$id] == NULL)
			{
				$this-> js_action_vars[$id] = array();
			}
			$this-> js_action_vars[$id][$action] = array();
			$this-> js_action_vars[$id][$action]["data"] = $js_actions;
		}
		//echo $data;	
	}

	// this is to evaluate javascript statments.
	public function evaluate_action_for_js($parse_tree, $tokens)
	{
		$script_text = "";
		if($parse_tree->type == statement::$IF)
		{
			$script_text .= $this->evaluate_if_statment_for_js($parse_tree, $tokens);
		}
		elseif($parse_tree->type == statement::$STATEMENT)
		{			
		    foreach($parse_tree->childs as $node) //hope thre would be only one.
			{
				$script_text .= $this->evaluate_action_for_js($node, $tokens);
				if( $node->type != statement::$STATEMENT  && $node->type != statement::$IF)
				{
					$script_text .= ";\n";
				}
			}
		}
		else
		{
			$script_text .=$this->evaluate_expression_for_js($parse_tree, $tokens);
		}
		return $script_text;
	}
	
	
	public function evaluate_expression_for_js($parse_tree, $tokens)
	{
		$script_text = "";
		if($parse_tree->type == statement::$EXPR )
		{
			$script_text .= "(";
			foreach($parse_tree->childs as $node)
			{
				$script_text .= $this->evaluate_expression_for_js($node, $tokens);
			}
			$script_text .= ")";
		}
		elseif($parse_tree->type == statement::$FUNCTION)
		{
			$funct_start = $parse_tree->childs["expr1"]; //the constant and the token..
			$funct_name = $this->get_token_value($funct_start, $tokens);

			if(funct::$functs[$funct_name] == NULL)
			{
				$this->report_error("Function name not defined..\n");
				return -1;
			}
			elseif(funct::$functs[$funct_name]["js"] == NULL)
			{
				$this->js_possible = false;
				return "";
			}
			
			$param_tree = $parse_tree->childs["expr2"];
			$params = $this->parse_params($param_tree, $tokens, "js");
	
			$count = count($params);
			$script_text .= "SEMF.funct.".$funct_name."(";
			for($i = 0; $i < $count; $i ++)
			{
				$script_text .= $params[$i];
				if($i != $count -1)
				{
					$script_text .= ", ";
				}
			}
			$script_text .= ")";
		}
		elseif($parse_tree->type == statement::$EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " = ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$EQUILITY)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " == ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$NOT_EQUILITY)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " != ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$LESS_THAN)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " < ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$GREATER_THAN)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " > ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		//dot should be handled different way
		/*elseif($parse_tree->type == statement::$DOT)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " . ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		} */
		elseif($parse_tree->type == statement::$ADD)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " + ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SUB)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " - ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$MUL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " = ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " * ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$ADD_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " += ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SUB_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " -= ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$MUL_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " *= ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " /= ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}elseif($parse_tree->type == statement::$OR)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " || ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$AND)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " && ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DOT)
		{
			$script_text .= $this->evaluate_expression_for_js($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " . ".
							$this->evaluate_expression_for_js($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		
		elseif($parse_tree->type == statement::$VARIABLE) // these are page variables
		{
			$var_name = $this->get_token_value($parse_tree, $tokens);
			//$script_text .= $this->page_namespace."page_".$var_name;
			$script_text .= $this->page_namespace."_".$var_name;
			$this->page_js_vars[$var_name] = "";
		}
		elseif($parse_tree->type == statement::$CONSTANT) // these are page variables
		{
			$script_text .= "\"".$this->get_token_value($parse_tree, $tokens)."\"";
		}
		elseif($parse_tree->type == statement::$NUMBER) // these are page variables
		{
			$script_text .= " ".$this->get_token_value($parse_tree, $tokens)." ";
		}
		elseif($parse_tree->type == statement::$NULL) // these are page variables
		{
			$script_text .= "null";
		}
		elseif($parse_tree->type == statement::$SYS_VAR) // these are page variables
		{
			$sys_var =  $this->get_token_value($parse_tree, $tokens);
			// the sys_var should be checked within a switch sooner or later:(
			if($sys_var == "today")
			{
				$code .= "SEMF.funct.get_today()";
			}
			else
			{
				$this->js_possible = false;
				//$this->report_error("Unknown System variable: ".$sys_var);
			}
			$script_text = $code;
		}
		elseif($parse_tree->type == statement::$DATA_VAR)
		{
			$this->js_possible = false;
		}
		//now parse the tokens which wont occur easily
		
		elseif($parse_tree->type == statement::$TOKEN)
		{
			for($i = $parse_tree->start; $i <= $parse_tree->end; $i ++)
			{
				$script_text .= $tokens[$i]->value;
			}
		}
		else
		{
			//try for not js
			$this->js_possible = false;
		}
		return $script_text;
	}
	
	public function evaluate_if_statment_for_js($parse_tree, $tokens)
	{
		$script_text = "";
		$i = 1;
		//print_r($parse_tree);
		while(true)
		{
			if(($stmt = $parse_tree->childs["stmt".$i]) != NULL)
			{
				if ($i != 1)
				{
					$script_text .= "else ";
				}
				if(($expr = $parse_tree-> childs["expr".$i]) != NULL)
				{
					$script_text .= "if";
					$script_text .= "";
					$script_text .= $this->evaluate_expression_for_js($expr, $tokens);
					$script_text .= "\n";
				}
				$script_text .= "{\n";
				$script_text .= $this->evaluate_action_for_js($stmt, $tokens);
				$script_text .= "\n}\n";
			}
			else
			{
				break;
			}
			$i ++;
		}
		return $script_text;
	}
	
	// this is to evaluate php statments.
	public function evaluate_action_for_php($parse_tree, $tokens)
	{
		$script_text = "";
		if($parse_tree->type == statement::$IF)
		{
			$this->pre_stmt_count ++;
			$php_code .= $this->evaluate_if_statment_for_php($parse_tree, $tokens);
			$this->pre_stmt_count --;
			//if($this->pre_stmt_count == 0)
			{
				$script_text .= $this->pre_stmt_code[$this->pre_stmt_count+1];
			}
			$script_text .= $php_code;
		
			if($this->pre_stmt_count == 0)
			{
				$this->pre_stmt_code = array();
				$this->pre_stmt_vars = array();
			}
		}
		elseif($parse_tree->type == statement::$STATEMENT)
		{
		    foreach($parse_tree->childs as $node) //hope thre would be only one.
			{
				$this->pre_stmt_count ++;
				$php_code = $this->evaluate_action_for_php($node, $tokens);
				$this->pre_stmt_count --;
				
				//if($this->pre_stmt_count == 0)
				{
					$script_text .= $this->pre_stmt_code[$this->pre_stmt_count+1];
				}
				$script_text .= $php_code;
			
				if($this->pre_stmt_count == 0)
				{
					$this->pre_stmt_code = array();
					$this->pre_stmt_vars = array();
				}
				
				if( $node->type != statement::$STATEMENT  && $node->type != statement::$IF &&
				    $node->type != statement::$DECL &&
				    $node->type != statement::$CAST &&
				    $node->type != statement::$DELETE &&
				    $node->type != statement::$SELECT &&
					$this->req_semi_col != false)
				{
					$script_text .= ";\n";
				}
				$this->req_semi_col = true;
			}
		}
		else
		{
			$this->pre_stmt_count ++;
			$php_code .=$this->evaluate_expression_for_php($parse_tree, $tokens);
			$this->pre_stmt_count --;
			//if($this->pre_stmt_count == 0)
			{
				$script_text .= $this->pre_stmt_code[$this->pre_stmt_count + 1];
			}
			$script_text .= $php_code;
		
			if($this->pre_stmt_count == 0)
			{
				$this->pre_stmt_code = array();
				$this->pre_stmt_vars = array();
			}	
		}
		return $script_text;
	}
	
	
	public function evaluate_expression_for_php($parse_tree, $tokens)
	{
		$script_text = "";
		if($parse_tree->type == statement::$EXPR )
		{
			$script_text .= "(";
			foreach($parse_tree->childs as $node)
			{
				$script_text .= $this->evaluate_expression_for_php($node, $tokens);
			}
			$script_text .= ")";
		}
		elseif($parse_tree->type == statement::$EQUAL)
		{
			$lhs = $parse_tree->childs["expr1"]->childs["expr1"];
			$rhs = $parse_tree->childs["expr2"]->childs["expr1"];
			$lhs_result = $rhs_result = NULL;
			if( $lhs-> type == statement::$DOT)
			{
				//for the update operation
				if ( $rhs-> type == statement::$DOT )
				{
					$this->report_error("both rhs and lhs can not be Database objects\n");
					return -1;
				}
				// this should be a variable anyway..
				$this->from_sql = "";
				$this->update_sql = "";
				$rhs_result = "";
				
				$code = ""; // here we have to write the code all by hand:(

				$rhs_data = NULL;
				if($rhs-> type == statement::$DATA_VAR)
				{					
					$var_name = $this->get_token_value($rhs, $tokens);
					if( $this->php_table_inout_vars[$var_name] == NULL)
					{
						$this->php_table_inout_vars[$var_name] = "";
					}
					$rhs_data = $var_name;
				}	
							
				$this->where_sql = 
			   		$this->parse_data_update_dot_expression($lhs, $tokens, NULL, NULL, $rhs_data);
				if($this->update_where_sql != NULL)
				{
					//this is an array for sure.. so go for deleteing everything ..
					//and adding things back..
					
					$addition_lhs = $this->addition_sql_lhs;
					$addition_rhs = $this->addition_sql_rhs; // this is a name of a variable.
					
					if(trim($this->update_where_sql) == "")
					{
						//just use the ids of the original variable itself.. no additinal queries..
						$code .= "\$updating_ids = array_keys(\$args['table']['".$addition_rhs."']);\n";
					}
					else
					{
						$the_sql = "SELECT ".$this->update_select_sql." FROM ".$this->from_sql." WHERE ".$this->update_where_sql;
		
						$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
						$code .= "\$data_table = array_keys(\$args['table']['".$addition_rhs."']); //just give another temporary_name\n";
							
						$code .= "\$query .=\"(\";\n";
						$code .= "\$total = count(\$data_table);\n";
						$code .= "if(\$total == 0)\n";
						$code .= "	\$query .= \"0\";\n";
						$code .= "\$i = 0;\n";
						$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
						$code .= "{\n";
						$code .= "	//complete the query dynamically..\n";
						$code .= "	\$query .= \"".$addition_lhs." = '\". \$data_value.\"'\";";
						$code .= "	\$i ++;\n";
						$code .= "	if(\$total != \$i)\n";
						$code .= "	{\n";
						$code .= "		\$query .= \" OR \";\n";
						$code .= "	}\n";
						$code .= "}\n";
						$code .= "\$query .=\")\";\n";	
						
						$code .= "// execute query\n";
						$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";	
			
						$code .= "\$updating_ids = array();\n";
						$code .= "\$i = 0;\n";
						$code .= "if (mysql_num_rows(\$result) > 0) \n";
						$code .= "{\n";
						$code .= "	while(\$row = mysql_fetch_row(\$result)) \n";
						$code .= "	{\n";
						$code .= "		// set the text\n";
						$code .= "		\$updating_ids[\$i] = \$row[0]; // this will give an id\n";
						$code .= "		\$i ++;\n";
						$code .= "	}\n";
						$code .= "} \n";					
					}
					//we now we have updating ids in \$updating_ids now just enter it what else...
					if($rhs-> type == statement::$DATA_VAR)
					{
						$var_name = $this->get_token_value($rhs, $tokens);
						if( $this->php_table_inout_vars[$var_name] == NULL)
						{
							$this->php_table_inout_vars[$var_name] = "";
						}
						$rhs_data = $var_name;
						$code .= "\$array_".$rhs_data." = array_keys(\$args['table']['".$rhs_data."']);\n";
						$rhs_result = "\$array_".$rhs_data."[\$i]";
					}
					else
					{
						$rhs_result = ".".$this->evaluate_expression_for_php($rhs, $tokens).".";
					}

					//deleting all the remaining which are in the updatinng id..
					$code .= "\$rhs = ".$rhs_result.";\n";
					$the_sql = "DELETE FROM ".$this->update_array_table_entry." WHERE ";
					$code .= "\$query = \"".$the_sql."\";\n";
					$code .= "foreach(\$updating_ids as \$updating_id)\n";
					$code .= "{\n";
					$code .= "	\$this_query = \$query.\"{$this->update_array_table_entry}.id = \$updating_id \";\n";
					//error handling are done right here..
					$check_sql = "SELECT ".$this->update_array_table_entry.".id FROM ".
									$this->update_array_table_entry." WHERE ".
									$this->update_array_table_entry.".id = \$updating_id";
					$code .= "	\$check_sql = \"".$check_sql."\";\n";
					$code .= "	\$result = mysql_query(\$check_sql) or die (\"Error in query: \$check_sql \".mysql_error());\n";
					$code .= "	if (mysql_num_rows(\$result) > 0)\n";
					$code .= "	{\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";
					$code .= "}\n";	
										
					
					// the intermediate step..
					if($rhs-> type == statement::$DATA_VAR)
					{
						$code .= "for(\$i = 0; \$i < count(\$array_".$rhs_data."); \$i ++)\n";
						$code .= "{\n";
					}
					
					$the_sql = "INSERT INTO ".$this->update_array_table. " VALUES";
					$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
					$code .= "\$rhs = ".$rhs_result.";\n";
					
					$code .= "foreach(\$updating_ids as \$updating_id)\n";
					$code .= "{\n";
					$code .= "	\$this_query = \$query.\" ( \".\$updating_id.\",\".\$rhs.\")\";\n";
					//error handling are done right here..
					$check_sql = "SELECT ".$this->update_array_table_entry.".id FROM ".
									$this->update_array_table_entry." WHERE ".
									$this->update_field_name. " = \$rhs AND ".
									$this->update_array_table_entry.".id = \$updating_id";
					$code .= "	\$check_sql = \"".$check_sql."\";\n";
					$code .= "	\$result = mysql_query(\$check_sql) or die (\"Error in query: \$check_sql \".mysql_error());\n";
					$code .= "	if (mysql_num_rows(\$result) == 0)\n";
					$code .= "	{\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";
					$code .= "}\n";
					
					//just close the bracket..
					if($rhs-> type == statement::$DATA_VAR)
					{
						$code .= "}\n //end of the if statment\n";
					}
					
					$script_text .= $code;
					
					return $script_text;
					
					
				} //end of the is array stuff..

				$rhs_data = NULL;
				if($rhs-> type == statement::$DATA_VAR)
				{
					$var_name = $this->get_token_value($rhs, $tokens);
					if( $this->php_table_inout_vars[$var_name] == NULL)
					{
						$this->php_table_inout_vars[$var_name] = "";
					}
					
					$rhs_data = $var_name;
					$code .= "\$array_".$rhs_data." = array_keys(\$args['table']['".$rhs_data."']);\n";
					$rhs_result = "\$array_".$rhs_data."[0]";
				}
				else
				{
					$rhs_result = $this->evaluate_expression_for_php($rhs, $tokens);
				}
									
				$the_sql = "UPDATE ".$this->from_sql;
				
				$the_sql.= " SET ".$this->update_sql." = '\".".$rhs_result.".\"'";
				$the_sql .= " WHERE ".$this->where_sql;
				
				$addition_lhs = $this->addition_sql_lhs;
				$addition_rhs = $this->addition_sql_rhs; // this is a name of a variable.
	
				$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
				$code .= "\$data_table = array_keys(\$args['table']['".$addition_rhs."']); //just give another temporary_name\n";
	
				$code .= "\$query .=\"(\";\n";
				$code .= "\$total = count(\$data_table);\n";
				$code .= "if(\$total == 0)\n";
				$code .= "	\$query .= \"0\";\n";
				$code .= "\$i = 0;\n";
				$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
				$code .= "{\n";
				$code .= "	//complete the query dynamically..\n";
				$code .= "	\$query .= \"".$addition_lhs." = '\". \$data_value.\"'\";";
				$code .= "	\$i ++;\n";
				$code .= "	if(\$total != \$i)\n";
				$code .= "	{\n";
				$code .= "		\$query .= \" OR \";\n";
				$code .= "	}\n";
				$code .= "}\n";
				$code .= "\$query .=\")\";\n";	
				
				$code .= "// execute query\n";
				$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
				$script_text .= $code;
				
								
				$this->req_semi_col = false;
				return $script_text;
			}
			else
			{
				$lhs_result = $this->evaluate_expression_for_php($lhs, $tokens);
			}
			
			if( $rhs-> type == statement::$DOT)
			{
				if ( $lhs-> type == statement::$DOT )
				{
					$this->report_error("both rhs and lhs can not be Database objects\n");
					return -1;
				}
				$this->from_sql = "";
				$this->select_sql = "";
				$this->where_sql = 
			   		$this->parse_data_retrieve_dot_expression($rhs, $tokens, NULL, NULL);
					
				$the_sql = $this->build_select_sql_string(); // compulsorily the select statement..
				if($this->where_sql == NULL || trim($this->where_sql) == "")
				{
					$the_sql .= " WHERE "; // we need the where to this only..
				}
				$addition_lhs = $this->addition_sql_lhs;
				$addition_rhs = $this->addition_sql_rhs; // this is a name of a variable.
				
				$code = ""; // here we have to write the code all by hand:(
				$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
				$code .= "\$data_table = array_keys(\$args['table']['".$addition_rhs."']); //just give another temporary_name\n";
	
				$code .= "\$query .=\"(\";\n";
				$code .= "\$total = count(\$data_table);\n";
				$code .= "if(\$total == 0)\n";
				$code .= "	\$query .= \"0\";\n";
				$code .= "\$i = 0;\n";
				$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
				$code .= "{\n";
				$code .= "	//complete the query dynamically..\n";
				$code .= "	\$query .= \"".$addition_lhs." = '\". \$data_value.\"'\";";
				$code .= "	\$i ++;\n";
				$code .= "	if(\$total != \$i)\n";
				$code .= "	{\n";
				$code .= "		\$query .= \" OR \";\n";
				$code .= "	}\n";
				$code .= "}\n";
				$code .= "\$query .=\")\";\n";	
				
				$code .= "// execute query\n";
				$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
				

				$code .= "// see if any rows were returned\n";
				$code .= "if (mysql_num_rows(\$result) > 0) \n";
				$code .= "{\n";
				$code .= "	while(\$row = mysql_fetch_row(\$result)) \n";
				$code .= "	{\n";
				$code .= "		// set the text, hope this is text..\n";
				$code .= "		".$lhs_result." = \$row[1]; // since the player id is retrieved as row[0]\n";
				//$code .= "		".$lhs_result." = \$row[0];//Here row[0] should be considered\n";
				$code .= "	}\n";
				$code .= "} \n";
				
				$script_text .= $code;
				
				//echo $code;
				$this->req_semi_col = false;							
			}
			else if( $rhs-> type == statement::$DATA_VAR)
			{
				if($lhs-> type == statement::$VARIABLE)
				{
					$lhs_result = $this->evaluate_expression_for_php($lhs, $tokens);
					
					$var_name = $this->get_token_value($rhs, $tokens);
					if( $this->php_table_inout_vars[$var_name] == NULL)
					{
						$this->php_table_inout_vars[$var_name] = "";
					}
					$pre_code = "\$tmp = array_keys(\$args['table']['".$var_name."']);\n";
					$this->pre_stmt_code[$this->pre_stmt_count] .= $pre_code;
					
					$script_text .= $lhs_result. 
									" = ".
									"\$tmp[0]";
				}
				else
				{
					$this->report_error("Data variables can only be assigned to page variables");
				}
			}
			elseif($lhs-> type != statement::$DOT)
			{
				$rhs_result = $this->evaluate_expression_for_php($rhs, $tokens);
				$script_text .= $lhs_result.
								" = ".
								$rhs_result;
			}
		}
		elseif($parse_tree->type == statement::$EQUILITY)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " == ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$NOT_EQUILITY)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " != ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SELECT)
		{
			$this->evaluate_database_select($parse_tree, $tokens);
			$the_sql = $this->build_select_sql_string(); // compulsorily the select statement..
			if($this->where_sql == NULL || trim($this->where_sql) == "")
			{
				//$the_sql .= " WHERE "; // we need the where to this only..
			}
			$current_table = $this->current_table;
			
			
			$code = ""; // here we have to write the code all by hand:(
			$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
			if($this->where_sql != NULL && trim($this->where_sql) != "" &&
						$this->select_support_code != "")
			{
				$code .= "\$query .= \" AND \";\n";
			}
			$code .= $this->select_support_code; //some additional tables..
			
			$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
			
			$code .= "	\$args['table']['".$current_table."'] = array(); //initializing appropriately\n";
			$code .= "	// see if any rows were returned\n";
			$code .= "	if (mysql_num_rows(\$result) > 0) \n";
			$code .= "	{\n";
			$code .= "		while(\$row = mysql_fetch_row(\$result)) \n";
			$code .= "		{\n";
			$code .= "			// set the text\n";
			$code .= "			\$id = \$row[0]; // this will give an id\n";
			$code .= "			\$args['table']['".$current_table."'][\$id] = array(\"id\" => \$id);\n";
			$code .= "		}\n";
			$code .= "	} \n";	
			
			$script_text .= $code;
		}
		elseif($parse_tree->type == statement::$DELETE)
		{
			$this->parse_data_delete_expression($parse_tree, $tokens);
			
			$current_table_var= $this->current_table;
			$current_table_schema = $this->table_vars[$current_table_var];
			
			
			$the_sql = "DELETE FROM ".$current_table_schema. " WHERE ";
			
			$code = ""; // here we have to write the code all by hand:(
			$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
			$code .= "\$ids = array_keys(\$args['table']['".$current_table_var."']);\n";
			$code .= "\$i = 0;\n";
			$code .= "foreach(\$ids as \$id)\n";
			$code .= "{\n";
			$code .= "	if(\$i != 0)\n";
			$code .= "	{\n";
			$code .= "	 	\$query = \$query.\" OR \";\n";
			$code .= "	 	\n";
			$code .= "	}\n";
			$code .= "	\$i ++;\n";
			$code .= "	//complete the query dynamically..\n";
			$code .= "	\$query = \$query.\"".$current_table_schema.".id = \". \$id;\n";
			$code .= "}\n";
			$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
							
			$code .= "\n";
			$script_text .= $code;		
			
		}
		elseif($parse_tree->type == statement::$DECL)
		{
			$this->parse_data_declare_expression($parse_tree, $tokens);
			
			$current_table_var= $this->current_table;
			$current_table_schema = $this->table_vars[$current_table_var];
			
			$current_table_var_in_page = "\$args['table']['".$this->current_table."']";
			
			$code = ""; // here we have to write the code all by hand:(
			
			$code .= "//creating the new table..\n";
			$code .= $current_table_var_in_page." = array();\n";
			
			$the_sql = "INSERT INTO ".$current_table_schema. " (__newly_created) values (true)";
			
			$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
			$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error());\n";
			$code .= "\$last_id = mysql_insert_id();\n";
			$code .= $current_table_var_in_page."[\$last_id] = array('id'=> \$last_id);\n";
							
			$code .= "\n";
			$script_text .= $code;
			
			//TODO: here we should fill whatever it should need to fill the parents..
			
		}
		elseif($parse_tree->type == statement::$CAST)
		{
			//first varify the cast is possible..
			$old_table_var = $this->parse_data_cast_expression($parse_tree, $tokens);
			$old_table_schema = $this->table_vars[$old_table_var];
			
			$current_table_var = $this->current_table;
			$current_table_schema = $this->table_vars[$current_table_var];
			
			
			$code = ""; // here we have to write the code all by hand:(
			
			$code .= "//retriving the parent ids from child..\n";
			
			$the_sql = "SELECT __".$current_table_schema." FROM ".$old_table_schema. " WHERE";	

			$code = ""; // here we have to write the code all by hand:(
			$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
			$code .= "\$data_table = array_keys(\$args['table']['".$old_table_var."']); //just give another temporary_name\n";

			$code .= "\$query .=\"(\";\n";
			$code .= "\$total = count(\$data_table);\n";
			$code .= "if(\$total == 0)\n";
			$code .= "	\$query .= \"0\";\n";
			$code .= "\$i = 0;\n";
			$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
			$code .= "{\n";
			$code .= "	//complete the query dynamically..\n";
			$code .= "	\$query .= \"id = '\". \$data_value.\"'\";";
			$code .= "	\$i ++;\n";
			$code .= "	if(\$total != \$i)\n";
			$code .= "	{\n";
			$code .= "		\$query .= \" OR \";\n";
			$code .= "	}\n";
			$code .= "}\n";
			$code .= "\$query .=\")\";\n";	
			$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
			
			$code .= "	\$args['table']['".$current_table_var."'] = array(); //initializing appropriately\n";
			$code .= "	// see if any rows were returned\n";
			$code .= "	if (mysql_num_rows(\$result) > 0) \n";
			$code .= "	{\n";
			$code .= "		while(\$row = mysql_fetch_row(\$result)) \n";
			$code .= "		{\n";
			$code .= "			// set the text\n";
			$code .= "			\$id = \$row[0]; // this will give an id\n";
			$code .= "			\$args['table']['".$current_table_var."'][\$id] = array(\"id\" => \$id);\n";
			$code .= "		}\n";
			$code .= "	} \n";
			
			$code .= "\n";
			$script_text .= $code;										
						
		}
		elseif($parse_tree->type == statement::$FUNCTION)
		{
			$funct_start = $parse_tree->childs["expr1"]; //the constant and the token..
			$funct_name = $this->get_token_value($funct_start, $tokens);
			

			if(funct::$functs[$funct_name]["php"] == NULL)
			{
				$this->report_error("Wrong context for the function.. ".$funct_name);
				return -1;
			}	
			
			$param_tree = $parse_tree->childs["expr2"];
			$params = $this->parse_params($param_tree, $tokens, "php");
	
			$count = count($params);
			
			//generate a unique name for the temp variables..
			$intro_var_name_prefix = "temp_var";
			$intro_var_name = "";
			$post_fix = 0;
			do
			{
				$intro_var_name = $intro_var_name_prefix.$post_fix;
				$post_fix ++;
			}
			while($this->pre_stmt_vars[$intro_var_name] == 1);
			$this->pre_stmt_vars[$intro_var_name] = 1;
			
			$code = "\$".$intro_var_name." = ";
			$code .= "funct_".$funct_name."( array(";
			for($i = 0; $i < $count; $i ++)
			{
				$code .= $params[$i];
				if($i != $count -1)
				{
					$code .= ", ";
				}
			}
			$code .= "), \$args['sys']);\n";
			$this->pre_stmt_code[$this->pre_stmt_count] .= $code; //just to verify..
			$this->pre_stmt_code[$this->pre_stmt_count] .= "\$args['sys'] = \$".$intro_var_name."[1];\n";
			
			$script_text .= "\$".$intro_var_name."[0]";
		}
		elseif($parse_tree->type == statement::$LESS_THAN)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " < ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$GREATER_THAN)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " > ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		//dot should be handled different way
		/*elseif($parse_tree->type == statement::$DOT)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " . ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		} */
		elseif($parse_tree->type == statement::$ADD)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " + ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$SUB)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " - ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$MUL)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " = ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " * ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$ADD_EQUAL ||
				$parse_tree->type == statement::$SUB_EQUAL)
		{
			$lhs = $parse_tree->childs["expr1"]->childs["expr1"];
			$rhs = $parse_tree->childs["expr2"]->childs["expr1"];
			$lhs_result = $rhs_result = NULL;
			if( $lhs-> type == statement::$DOT)
			{
				//for the update operation
				if ( $rhs-> type == statement::$DOT )
				{
					$this->report_error("both rhs and lhs can not be Database objects\n");
					return -1;
				}
				// this should be a variable anyway..
				$this->from_sql = "";
				$rhs_result = "";
				
				$code = ""; // here we have to write the code all by hand:(
				
				$rhs_data = NULL;
				if($rhs-> type == statement::$DATA_VAR)
				{
					$var_name = $this->get_token_value($rhs, $tokens);
					if( $this->php_table_inout_vars[$var_name] == NULL)
					{
						$this->php_table_inout_vars[$var_name] = "";
					}
					$rhs_data = $var_name;
					$code .= "\$array_".$rhs_data." = array_keys(\$args['table']['".$rhs_data."']);\n";
					$code .= "for(\$i = 0; \$i < count(\$array_".$rhs_data."); \$i ++)\n";
					$code .= "{\n";
					$rhs_result = "\$array_".$rhs_data."[\$i]";
				}
				else
				{
					$rhs_result = ".".$this->evaluate_expression_for_php($rhs, $tokens).".";
				}
				
				$this->where_sql = 
			   		$this->parse_data_update_dot_expression($lhs, $tokens, NULL, NULL, $rhs_data);
					
				//now we are going to act little different..
				if($this->update_where_sql == NULL)
				{
					$this->report_error("Seems you have mistakenly use += instead of =".
										" .. it is not an array you are adding things");
					return -1;
				}
				$addition_lhs = $this->addition_sql_lhs;
				$addition_rhs = $this->addition_sql_rhs; // this is a name of a variable.
				
				if(trim($this->update_where_sql) == "")
				{
					//just use the ids of the original variable itself.. no additinal queries..
					$code .= "\$updating_ids = array_keys(\$args['table']['".$addition_rhs."']);\n";
				}
				else
				{
					$the_sql = "SELECT ".$this->update_select_sql." FROM ".$this->from_sql." WHERE ".$this->update_where_sql;
	
					$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
					$code .= "\$data_table = array_keys(\$args['table']['".$addition_rhs."']); //just give another temporary_name\n";
						
					$code .= "\$query .=\"(\";\n";
					$code .= "\$total = count(\$data_table);\n";
					$code .= "if(\$total == 0)\n";
					$code .= "	\$query .= \"0\";\n";
					$code .= "\$i = 0;\n";
					$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
					$code .= "{\n";
					$code .= "	//complete the query dynamically..\n";
					$code .= "	\$query .= \"".$addition_lhs." = '\". \$data_value.\"'\";";
					$code .= "	\$i ++;\n";
					$code .= "	if(\$total != \$i)\n";
					$code .= "	{\n";
					$code .= "		\$query .= \" OR \";\n";
					$code .= "	}\n";
					$code .= "}\n";
					$code .= "\$query .=\")\";\n";	
					
					$code .= "// execute query\n";
					$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";	
		
					$code .= "\$updating_ids = array();\n";
					$code .= "\$i = 0;\n";
					$code .= "if (mysql_num_rows(\$result) > 0) \n";
					$code .= "{\n";
					$code .= "	while(\$row = mysql_fetch_row(\$result)) \n";
					$code .= "	{\n";
					$code .= "		// set the text\n";
					$code .= "		\$updating_ids[\$i] = \$row[0]; // this will give an id\n";
					$code .= "		\$i ++;\n";
					$code .= "	}\n";
					$code .= "} \n";					
				}
				//we now we have updating ids in \$updating_ids now just enter it what else...
				
				if($parse_tree->type == statement::$ADD_EQUAL)
				{
					$the_sql = "INSERT INTO ".$this->update_array_table. " VALUES";
						
					$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
					$code .= "\$rhs = ".$rhs_result.";\n";
					
					$code .= "foreach(\$updating_ids as \$updating_id)\n";
					$code .= "{\n";
					$code .= "	\$this_query = \$query.\" ( \".\$updating_id.\",\".\$rhs.\")\";\n";
					//error handling are done right here..
					$check_sql = "SELECT ".$this->update_array_table_entry.".id FROM ".
									$this->update_array_table_entry." WHERE ".
									$this->update_field_name. " = \$rhs AND ".
									$this->update_array_table_entry.".id = \$updating_id";
					$code .= "	\$check_sql = \"".$check_sql."\";\n";
					$code .= "	\$result = mysql_query(\$check_sql) or die (\"Error in query: \$check_sql \".mysql_error());\n";
					$code .= "	if (mysql_num_rows(\$result) == 0)\n";
					$code .= "	{\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";
					$code .= "}\n";
				}
				elseif($parse_tree->type == statement::$SUB_EQUAL)
				{

					$code .= "\$rhs = ".$rhs_result.";\n";
					$the_sql = "DELETE FROM ".$this->update_array_table_entry." WHERE ";
					$the_sql .= $this->update_field_name. " = \$rhs AND ";
					$code .= "\$query = \"".$the_sql."\";\n";
					$code .= "foreach(\$updating_ids as \$updating_id)\n";
					$code .= "{\n";
					$code .= "	\$this_query = \$query.\"{$this->update_array_table_entry}.id = \$updating_id \";\n";
					//error handling are done right here..
					$check_sql = "SELECT ".$this->update_array_table_entry.".id FROM ".
									$this->update_array_table_entry." WHERE ".
									$this->update_field_name. " = \$rhs AND ".
									$this->update_array_table_entry.".id = \$updating_id";
					$code .= "	\$check_sql = \"".$check_sql."\";\n";
					$code .= "	\$result = mysql_query(\$check_sql) or die (\"Error in query: \$check_sql \".mysql_error());\n";
					$code .= "	if (mysql_num_rows(\$result) > 0)\n";
					$code .= "	{\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";
					$code .= "}\n";	
				}
				//just close the bracket..
				if($rhs-> type == statement::$DATA_VAR)
				{
					$code .= "}\n //end of the if statment\n";
				}
				
				$script_text .= $code;
				
				$this->req_semi_col = false;
			}
			else
			{
				$lhs_result = $this->evaluate_expression_for_php($lhs, $tokens);
				$rhs_result = $this->evaluate_expression_for_php($rhs, $tokens);
				
				$script_text .= $lhs_result;
				if($parse_tree->type == statement::$ADD_EQUAL)
				{
					$script_text .= " += ";
				}
				elseif($parse_tree->type == statement::$SUB_EQUAL)
				{
					$script_text .= " -= ";
				}
				$script_text .= $rhs_result;
			}
		}
		elseif($parse_tree->type == statement::$MUL_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " *= ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DIV_EQUAL)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " /= ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}elseif($parse_tree->type == statement::$OR)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " || ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$AND)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " && ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		elseif($parse_tree->type == statement::$DOT)
		{
			$script_text .= $this->evaluate_expression_for_php($parse_tree->childs["expr1"]->childs["expr1"], $tokens).
			                " . ".
							$this->evaluate_expression_for_php($parse_tree->childs["expr2"]->childs["expr1"], $tokens);
		}
		
		elseif($parse_tree->type == statement::$VARIABLE) // these are page variables
		{
			$var_name = $this->get_token_value($parse_tree, $tokens);
			$script_text .= "\$args['page']['".$var_name."']";
			$this->page_php_vars[$var_name] = "";
			$this->php_inout_vars[$var_name] = "";
		}
		elseif($parse_tree->type == statement::$CONSTANT) // these are page variables
		{
			$script_text .= "\"".$this->get_token_value($parse_tree, $tokens)."\"";
		}
		elseif($parse_tree->type == statement::$NUMBER) // these are page variables
		{
			$script_text .= " ".$this->get_token_value($parse_tree, $tokens)." ";
		}
		elseif($parse_tree->type == statement::$NULL) // these are page variables
		{
			$script_text .= "NULL";
		}
		elseif($parse_tree->type == statement::$SYS_VAR) // these are page variables
		{
			$sys_var =  $this->get_token_value($parse_tree, $tokens);
			// the sys_var should be checked within a switch sooner or later:(
			if($sys_var == "today")
			{
				//generate a unique name for the temp variables..
				$intro_var_name_prefix = "temp_var";
				$intro_var_name = "";
				$post_fix = 0;
				do
				{
					$intro_var_name = $intro_var_name_prefix.$post_fix;
					$post_fix ++;
				}
				while($this->pre_stmt_vars[$intro_var_name] == 1);
				$this->pre_stmt_vars[$intro_var_name] = 1;
				
				$code = "\$".$intro_var_name." = ";
				$code .= "funct_get_today(array(), \$args['sys']);\n";
				$this->pre_stmt_code[$this->pre_stmt_count] .= $code; //just to verify..
				$script_text .= "\$".$intro_var_name."[0]";
			}
			elseif($sys_var == "this_user")
			{
				$intro_var_name_prefix = "temp_var";
				$intro_var_name = "";
				$post_fix = 0;
				do
				{
					$intro_var_name = $intro_var_name_prefix.$post_fix;
					$post_fix ++;
				}
				while($this->pre_stmt_vars[$intro_var_name] == 1);
				$this->pre_stmt_vars[$intro_var_name] = 1;
				
				$code = "\$".$intro_var_name." = ";
				$code .= "funct_get_this_user(array(), \$args['sys']);\n";
				$this->pre_stmt_code[$this->pre_stmt_count] .= $code; //just to verify..
				$script_text .= "\$".$intro_var_name."[0]";
			}
			elseif($sys_var == "this_user_type")
			{
				$script_text .= "\$args['sys']['user_type']";
			}
			else
			{
				$this->report_error("Unknown System variable: ".$sys_var);
			}
		}
		elseif($parse_tree->type == statement::$DATA_VAR)
		{
			//do we have this occations some way.:( 
			// yea we have places like @player.country = @country; handled above
			// and how about func(@player);
			
			$var_name = $this->get_token_value($parse_tree, $tokens);
			if( $this->php_table_inout_vars[$var_name] == NULL)
			{
				$this->php_table_inout_vars[$var_name] = "";
			}
			
			$table_name = $this->table_vars[$var_name];
			
			$script_text .= "\$args['table']['".$var_name."']";
			
			$this->pre_stmt_code[$this->pre_stmt_count] .=
					"\$args['sys']['temp_params'][".$this->param_parser_count."] 
							= array('var'=> '${var_name}',
									'table'=> '${table_name}');\n";
					
		}
		//now parse the tokens which wont occur easily
		
		elseif($parse_tree->type == statement::$TOKEN)
		{
			for($i = $parse_tree->start; $i <= $parse_tree->end; $i ++)
			{
				$script_text .= $tokens[$i]->value;
			}
		}
		return $script_text;
	}
	
	public function evaluate_if_statment_for_php($parse_tree, $tokens)
	{
		$script_text = "";
		$i = 1;
		//print_r($parse_tree);
		while(true)
		{
			if(($stmt = $parse_tree->childs["stmt".$i]) != NULL)
			{
				if ($i != 1)
				{
					$script_text .= "else ";
				}
				if(($expr = $parse_tree-> childs["expr".$i]) != NULL)
				{
					$script_text .= "if";
					$script_text .= "";
					$script_text .= $this->evaluate_expression_for_php($expr, $tokens);
					$script_text .= "\n";
				}
				$script_text .= "{\n";
				$script_text .= $this->evaluate_action_for_php($stmt, $tokens);
				$script_text .= "\n}\n";
			}
			else
			{
				break;
			}
			$i ++;
		}
		return $script_text;
	}
	
	public function associate_action_list($action_list, $id)
	{
	
		$component_php_actions = $this->php_action_vars[$id];
		if(is_array($component_php_actions))
		{
			$actions = array_keys($component_php_actions);		
			/** iterate through all available action for the id */
			foreach ($actions as $action)
			{
				// no matter what says in action_list;)
				if(strtolower($action) == "onload")
				{
					$this->php_code_on_load .= 
						"// call function for $id \n".
						"\$output_vars = {$id}_{$action} (\$input_vars);\n"; 
					$this->php_code_on_load .= "\$input_vars = \$output_vars; //now input will be last outputs;)\n";
				}
				else
				{
					$action_arr = $action_list[$action];
					if($action_arr == NULL)
					{
						continue;
					}
					$action_element = $action_arr["elem1"];
					$action_name = $action_arr["action"];
					if($action_name == NULL || $action_element == NULL)
					{
						continue;
					}
					
					if($this->action_element_info[$action_element] == NULL)
					{
						$this->action_element_info[$action_element] = array();
					}
					$this->action_element_info[$action_element][count($this->action_element_info[$action_element])]
								= array("event_name"=> $action_name,
										"handler_name"=> "SEMF.".$id."_".$action,
										"clinet_side" => "false",
										"prebounded"=> "false");
				}
			}
		}

		$component_js_actions = $this->js_action_vars[$id];
		if(is_array($component_js_actions))
		{
			$actions = array_keys($component_js_actions);		
			/** iterate through all available action for the id */
			foreach ($actions as $action)
			{
			
				// no matter what says in action_list;)
				if(strtolower($action) == "onload")
				{
					// we are not having onload things in js code..
				}
				else
				{
					$action_arr = $action_list[$action];
					if($action_arr == NULL)
					{
						continue;
					}
					$action_element = $action_arr["elem1"];
					$action_name = $action_arr["action"];
					if($action_name == NULL || $action_element == NULL)
					{
						continue;
					}
					
					if($this->action_element_info[$action_element] == NULL)
					{
						$this->action_element_info[$action_element] = array();
					}
					$this->action_element_info[$action_element][count($this->action_element_info[$action_element])]
								= array("event_name"=> $action_name,
										"handler_name"=> "SEMF.".$id."_".$action,
										"clinet_side" => "true", //the only different to the php action..
										"prebounded"=> "false");
				}
			}
		}
	}
	
	private function copy_include_files($result_dir)
	{
		$dir_from = $this->semf_root."page_designer/script/files_to_copy/";
		if(!is_dir($result_dir))
		{
			mkdir($result_dir);
		}
		
		$relative_path = "../store/other/";
		$dir_to = $result_dir;
		
		
		$extensions = array( "js"=> 1, //js files
							 "php"=> 1, //php filesv
							 "ico"=> 1, //icons
							 "jpg"=> 1, //images
							 "css"=> 1, // ''
							 "gif"=> 1, // ''
							 );
		
		$this->copy_dir($dir_from, $result_dir, $relative_path, $extensions, false);
		
		$component_types = array_keys($this->component_types);
		
		
		foreach ($component_types as $type)
		{
			$dir_from = $this->semf_root."page_designer/components/${type}/files_to_copy/";
			if(is_dir($dir_from))
			{
				//just try to copy it
				$this->copy_dir($dir_from, $result_dir, $relative_path, $extensions, false);
			}
		}
	}
	
	private function copy_dir($src, $dest, $relative_path, $extensions, $not2include)
	{
		if( !is_dir($src) ) //then just try copying it
		{
			if (!copy($src, $dest))
			{
				$this->report_error("failed to copy ${src}...");
				return -1;
			}
			return 0;
		}
		$d = dir($src);

        $temp_files_arr = array();
		while (false !== ($file = $d->read()))
		{
            $temp_files_arr []= $file;
        }
        sort($temp_files_arr);

        foreach ($temp_files_arr as $file) {
            //echo $file."<br/>";
			if (($file{0} == '.') ||
				($file{0} == '..') ||
				($file{0} == '~'))
			{
				continue;
			}
			else if( is_dir($src.$file) )
			{
				if($file == "not2include")
				{
					$not2include = true;
				}
				
				if( !is_dir($dest.$file) ) //just check before creatng..
				{
					mkdir($dest.$file);
				}
				$ret = $this->copy_dir($src.$file."/", $dest.$file."/",
				                $relative_path.$file."/", $extensions, $not2include);
				if( $ret == -1 )
				{
					return -1;
				}
				continue;
			}
			
			$ext = NULL;
			$tok = strtok($file, ".");
			while ($tok)
			{
				$ext = $tok; //to find the last token.
			   	$tok = strtok(".");
			}
			
			if( $extensions[$ext] != NULL )
			{
				if (!copy($src.$file, $dest.$file))
				{
					$this->report_error("failed to copy ${php_source}.${$file}...");
					return -1;
				}
				//now check for special file types..
				if($not2include == false)
				{
					if (strtolower($ext) == "js")
					{
						$this->js_includes .= "<script src=\"${relative_path}${file}\"></script>\n";
					}
					elseif (strtolower($ext) == "php")
					{
						$this->php_includes .= "include_once(\"${relative_path}${file}\");\n";
					}
					elseif (strtolower($ext) == "css")
					{
						$this->css_includes .= 
					"<link href=\"${relative_path}${file}\" rel=\"stylesheet\" type=\"text/css\"/>\n";
					}
				}
			}
		}
		return 0;	
	}

	private function evaluate_databinding_database_expressions()
	{
		//print_r($this->databinding_vars);
		$code = "";
		$ids = array_keys($this->databinding_vars);
		foreach($ids as $id)
		{
			$properties = array_keys($this->databinding_vars[$id]);
			foreach($properties as $property)
			{
				if($this->databinding_vars[$id][$property]["data_query"] == NULL)
				{
					continue;
				}
				
				//echo $the_sql;
				
				$data_vars = array_keys($this->databinding_vars[$id][$property]["stack"]);
				$data_var = $data_vars[0];
				
				//echo $table_var;
				
				$var_name = "\$table_vars[\"${data_var}\"]";

				
				$code .= "if (\$starter == 1 || \n";
				$code .= "  (\$diff_vars[\"table\"][\"${data_var}\"] != NULL && \n".
				         "   \$diff_vars[\"table\"][\"${data_var}\"][\"changed\"] == 1))\n";
				$code .= "{\n";

				$addition_lhs = $this->databinding_vars[$id][$property]["addition_lhs"];
				$addition_rhs = $this->databinding_vars[$id][$property]["addition_rhs"]; // this is a name of a variable.
				$the_sql = $this->databinding_vars[$id][$property]["data_query"];
				$tailer_sql = $this->databinding_vars[$id][$property]["data_query_tailer"];
				
				$code .= ""; // here we have to write the code all by hand:(
				$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
				$code .= "if(is_array(\$args['table']['".$addition_rhs."']))\n";
				$code .= "{\n";
				$code .= "\$data_table = array_keys(\$args['table']['".$addition_rhs."']); //just give another temporary_name\n";
				$code .= "\$query .= \"".$tailer_sql."\";\n";
				$code .= "\$total = count(\$data_table);\n";
				$code .= "if(\$total != 0)\n";
				$code .= "{\n";
				$last_occurence = strchr($the_sql, "WHERE");
				if(trim($last_occurence) == "WHERE" || 
				  (trim($last_occurence) == "" &&  trim($tailer_sql) == "WHERE"))
				{
				}
				else
				{
					//$code .= "\$query .=\" AND \";\n";
				}
				$code .= "\$query .=\"(\";\n";
				$code .= "\$i = 0;\n";
				$code .= "foreach(\$data_table as \$data_value) // these are typically ids\n";
				$code .= "{\n";
				
				$code .= "	//complete the query dynamically..\n";
				$code .= "	\$query .= \"".$addition_lhs." = \". \$data_value;\n";
				$code .= "	\$i ++;\n";
				$code .= "	if(\$total != \$i)\n";
				$code .= "	{\n";
				$code .= "		\$query .= \" OR \";\n";
				$code .= "	}\n";
				$code .= "}\n";
				$code .= "\$query .=\")\";\n";
				$code .= "}\n";
				$code .= "else\n";
				$code .= "{\n";
				$last_occurence = strchr($the_sql, "WHERE");
				if(trim($last_occurence) == "WHERE" || 
				  (trim($last_occurence) == "" &&  trim($tailer_sql) == "WHERE"))
				{
					$code .= "\$query .=\"0\";\n";
				}
				else
				{
					//if the last 4 chars are 'and '
					$last_4chars = substr($the_sql, -4);
					if($last_4chars == "and ")
					{
					$code .= "\$query .=\"1\";\n";
					}
				}
				$code .= "}\n";
				
				$code .= "}\n";
				
				$code .= "\n";
				$code .= "// execute query\n";
				$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
				

				$code .= "	if(${var_name} == NULL)\n";
				$code .= "	{\n";
				$code .= "		${var_name} = array();\n";
				$code .= "	}\n";
				$code .= "// see if any rows were returned\n";
				$code .= "if (mysql_num_rows(\$result) > 0) \n";
				$code .= "{\n";
				$code .= "	while(\$row = mysql_fetch_row(\$result)) \n";
				$code .= "	{\n";
				$code .= "		// retrieve the id\n";
				$code .= "		\$id = \$row[0];\n";
				$code .= "		\n";
				$code .= "		if(${var_name}[\$id] == NULL)\n";
				$code .= "		{\n";
				$code .= "			${var_name}[\$id] = array();\n";
				$code .= "		}\n";
			
				$followed_var_name = "";
				//algorithm to return the followed_var_name
				$key = $data_var;
				$arr = $this->databinding_vars[$id][$property]["stack"];
				
				//print_r($arr);
				
				while($arr[$key] != NULL && is_array($arr[$key]))
				{
					//then it should be an array..
					$keys_arr = array_keys($arr[$key]);
					$the_key = $keys_arr[0]; // we know only one key exist for one expression..
					
					$followed_var_name .= "[\"".$the_key."\"]";

					$arr = $arr[$key];
					$key = $the_key;
					
					if($arr[$key] == NULL || !is_array($arr[$key]))
					{
						break;
					}
					
					$code .= "		if(${var_name}[\$id]${followed_var_name} == NULL)\n";
					$code .= "		{\n";
					$code .= "			${var_name}[\$id]${followed_var_name} = array();\n";
					$code .= "		}\n";
				
				}
				//echo $followed_var_name."\n";				
				$is_property_array = $this->databinding_vars[$id][$property]["update_array"];
				if($is_property_array)
				{
					$code .= "		if(${var_name}[\$id]${followed_var_name} == NULL)\n";
					$code .= "			${var_name}[\$id]${followed_var_name} = array();\n";
					$code .= "		\$position_i =  count(${var_name}[\$id]${followed_var_name});\n";
					$code .= "		${var_name}[\$id]${followed_var_name}[\$position_i] = \$row[1];\n";
				}
				else
				{
					$code .= "		${var_name}[\$id]${followed_var_name}= \$row[1]; //since the player id is retrieved as row[0]\n";
				}
				$code .= "	}\n";
				$code .= "} \n";
				$code .= "\n";
				
				$code .= "} //close the most outer if\n\n";
				
				
			}
		}
		$this->property_update_code = $code;
	}
	
	public function register_component_type($type)
	{
		$this->component_types[$type] = 1;
	}
	
	public function initial_js()
	{
		/*$this->js_code_global .= "var SEMF = {};\n";
		$this->js_code_on_load .= "SEMF[\"actlist\"] = {};\n";
		$this->js_code_on_load .= "SEMF[\"page\"] = {};\n";
		$this->js_code_on_load .= "SEMF[\"data\"] = {};\n"; */
		
	}
	
	public function build_event_handler_js_code()
	{
		$event_handler_map = "SEMF.eventHandlerMap = {\n";
		$event_handler_id_array = "SEMF.eventHandlerIdArray = [\n";
		
		
		$elements = array_keys($this->action_element_info);
		$element_count = 0;
		foreach($elements as $action_element)
		{
			$event_names = "";
			$handler_names = "";
			$client_sides = "";
			$preboundeds = "";
			
			$actions_count = count($this->action_element_info[$action_element]);
			for($i = 0; $i < $actions_count; $i ++)
			{
				if($i != 0)
				{
					$event_names .= ",";
					$handler_names .= ",";
					$client_sides .= ",";
					$preboundeds .= ",";		
				}
				
				$event_names .= "\"".$this->action_element_info[$action_element][$i]["event_name"]."\"";
				$handler_names .= $this->action_element_info[$action_element][$i]["handler_name"];
				$client_sides .= $this->action_element_info[$action_element][$i]["clinet_side"];
				$preboundeds .= $this->action_element_info[$action_element][$i]["prebounded"];
			}
			if($element_count != 0)
			{
				$event_handler_map .= ",\n";
				$event_handler_id_array .= ",\n";
			}
			$event_handler_map .= $action_element.":\n";
			$event_handler_map .= "{\n";
			$event_handler_map .= " events:[${event_names}],\n";
			$event_handler_map .= " handlers:[${handler_names}],\n";
			$event_handler_map .= " clientside:[${client_sides}],\n";
			$event_handler_map .= " prebounded:[${preboundeds}]\n";
			$event_handler_map .= "}\n";
			
			$event_handler_id_array .= "\"".$action_element."\"";
			
			$element_count ++;
		}
		$event_handler_map .= "};\n";
		$event_handler_id_array .= "];\n";
		
		$this->js_code_global .= "// list all the component ids associted with events..\n";
		$this->js_code_global .= $event_handler_id_array."\n";
		$this->js_code_global .= $event_handler_map."\n";
	}
	
	/**
	 * @arg property_list
	 * @arg id
	 */
	public function associate_property_list($property_list, $id)
	{
		$databindings = $this->databinding_vars[$id];
		if(is_array($databindings))
		{
			$properties = array_keys($databindings);		
			/** iterate through all available action for the id */
			foreach ($properties as $property)
			{
				$property_arr = $property_list[$property];
				if($property_arr == NULL)
				{
					continue;
				}
				$property_element = $property_arr["databind"];
				$property_attri = $property_arr["attri"]; //not used..
				
				if($property_element == NULL)
				{
					$property_element = $property_arr["databind2"];
					
					if($property_element == NULL)
					{
						continue;
					}
					$this->databinding_vars[$id][$property]["secondary"] = true;
				}
				$this->databinding_vars[$id][$property]["databind"] = $property_element;
			}
		}
	}
	
	
	public function build_property_data_info()
	{
		//print_r($this->databinding_vars);
		$property_info_array = "SEMF.propertyInfoArray = [\n";
		$property_data_map = "SEMF.propertyDataMap = {\n";
		
		$ids = array_keys($this->databinding_vars);
		$i = 0;
		$j = 0;
		foreach($ids as $id)
		{
			$databindings = $this->databinding_vars[$id];
			$properties = array_keys($databindings);		
			/** iterate through all available action for the id */
			foreach ($properties as $property)
			{
				$property_element = $databindings[$property]["databind"];
				$secondary = $databindings[$property]["secondary"];
				$type = $databindings[$property]["type"];
				$is_array = $databindings[$property]["update_array"];
				
				
				if($property_element == NULL)
				{
					continue;
				}
				if($i != 0)
				{
					$property_info_array .= ",\n";
				}
				$property_info_array .= "{\n";
				$property_info_array .= "property: \"".$property_element."\",\n";
				$property_info_array .= "type: \"".$type."\",\n";
			
				if($secondary == true)
				{
					$property_info_array .= "secondary: true,\n";
				}
				
				if($type == "data") //then this is a table variable
				{
					if($j != 0)
					{
						$property_data_map .= ",\n";
					}
					
					$property_data_map .=  "\"".$property_element."\":[";
					
					$stack = $databindings[$property]["stack"];
					$data_varbs = array_keys($stack);//there would be only one
					$data_varb = $data_varbs[0];
					$k = 0;
					do
					{
						if($k != 0)
						{
							$property_data_map .= ",";
						}
						$keys = array_keys($stack);
						$key = $keys[0];
						$property_data_map .= "\"".$key."\"";
						$stack = $stack[$key];
						
						$k ++;
					}
					while(is_array($stack));
					
					$property_data_map .= "]";
					
					if($is_array == 1)
					{
						$property_info_array .= "isarray: ".$is_array.",\n";
					}
					$property_info_array .= "varb: \"".$data_varb."\"\n";
					$j ++;
				}
				else if($type == "var")
				{
					$property_info_array .= "varb: \"_".$databindings[$property]["value"]."\"\n";
				}
				else //for consts..
				{
					$property_info_array .= "varb: \"".$databindings[$property]["value"]."\"\n";
				}
				
				$property_info_array .= "}";
				
				$i ++;
			}
		}	
		$property_info_array .= "\n];\n";
		$property_data_map .= "\n};\n";
		$this->js_code_global .= "// list all the component ids associted with databindings..\n";
		$this->js_code_global .= $property_info_array."\n";
		$this->js_code_global .= $property_data_map."\n";
	}
	
	private function init_js_vars_code()
	{
		$var_names = array_keys($this->page_js_vars);
		foreach($var_names as $var_name)
		{
			//TODO: Initialize only uninitialized vars..
			$value = $this->page_js_vars[$var_name];
			//$this->php_code_on_load_init_js .= "\$input_vars['page']['".$var_name."'] = ".
			//									"\"".$value."\";\n";
		} 
		$php_var_names = array_keys($this->page_php_vars);
		foreach($php_var_names as $var_name)
		{
			//echo $var_name.":".$this->page_js_vars[$var_name]."\n";
			if(!isset($this->page_js_vars[$var_name])) //we dont want duplicate initializations
			{
				$value = $this->page_php_vars[$var_name];
				//$this->php_code_on_load_init_js .= "\$input_vars['page']['".$var_name."'] = ".
				//								"\"".$value."\";\n";
			}
		}
	}
	
	private function php_actions_request_code()
	{
		$ids = array_keys($this->php_action_vars);
		foreach($ids as $id)
		{
			$component_php_actions = $this->php_action_vars[$id];
			if(is_array($component_php_actions))
			{
				$actions = array_keys($component_php_actions);		
				/** iterate through all available action for the id */
				foreach ($actions as $action)
				{			
					$data = "var varInOuts = [";
					$inouts = array_keys($this->php_action_vars[$id][$action]["inout"]);
					$i = 0;
					foreach($inouts as $inout)
					{
						if($i != 0)
						{
							$data .= ",\n";
						}
						$data .= "\"pg_".$inout."\", SEMF.page._".$inout;
						$i ++;
					}
					$data .= "];\n";
					
					$data .= "var tableInOuts = [";
					$table_inouts =
						 array_keys($this->php_action_vars[$id][$action]["table_inout"]);
					$i = 0;
					foreach($table_inouts as $inout)
					{
						if($i != 0)
						{
							$data .= ",\n";
						}
						$data .= "\"dt_".$inout."\", SEMF.listIdsFor(\"".$inout."\")";
						$i ++;
					}
					$data .= "];\n";
					
					$data .= "var inherited = [];\n";
					$data .= "if(arguments.length == 2 && arguments[0] == \"params\")\n";
					$data .= "{\n";
					$data .= " inherited = arguments[1];\n";
					$data .= "}\n";
					
					$data .= "var functName = [\"funct_name\", \"".$id."_".$action."\"];\n";
					
					$data .= 
					  "var paramArray = varInOuts.concat(tableInOuts, inherited, functName);\n";
					
					$data .= "SEMF.request(SEMF.dataModelFileName,\n";
					$data .= "{\n";
					$data .= "  success: SEMF.handleSuccess,\n";
					$data .= "  failure: SEMF.handleFailure,\n";
					$data .= "  argument: {\n";
					$data .= "	  ps: SEMF.onFinishDataUpdate\n";
					$data .= "  },\n";
					$data .= "  timeout: 5000,\n";
					$data .= "  params: paramArray\n";
					$data .= "});\n";
					
					
					$this->php_action_vars[$id][$action]["js_data"] = $data;
				}
			}
		}
	}
	private function databinding_updater_code()
	{
		$this->databinding_updater .= 
			"//responsible for update the databound properties\n";
		$this->databinding_updater .= 
			"function databinding_updater(\$property_name, \$data_id, \$value, \$add_remove)\n";
		$this->databinding_updater .= "{\n";
		$this->databinding_updater .= "if(\$property_name == NULL)\n";
		$this->databinding_updater .= "{\n";
		$this->databinding_updater .= " return;\n";
		$this->databinding_updater .= "}\n\n";
		$this->databinding_updater .= "\$update_query = NULL;\n\n";
			
		$ids = array_keys($this->databinding_vars);
		$i = 0;
		foreach($ids as $id)
		{
			$databindings = $this->databinding_vars[$id];
			$properties = array_keys($databindings);		
			/** iterate through all available action for the id */
			foreach ($properties as $property)
			{
				$type = $databindings[$property]["type"];
				
				if($type != "data") //only data type properties are considered..
				{
					continue;
				}
				$update_query = $databindings[$property]["data_update"];
				$property_element = $databindings[$property]["databind"];
				$is_property_array = $databindings[$property]["update_array"];
				
				$this->databinding_updater .= 
						"// update query for {$property_element}\n";
				if( $i != 0)
				{
					$this->databinding_updater .= "else ";
				}
				$this->databinding_updater .= "if(\$property_name == \"".$property_element."\")\n";
				$this->databinding_updater .= "{\n";
				if($is_property_array)
				{
					$update_where_sql = $databindings[$property]["update_where"];
					$update_select_sql = $databindings[$property]["update_select"];
					$from_sql = $databindings[$property]["update_from"];
					$update_table = $databindings[$property]["update_table"];
					$update_table_entry = $databindings[$property]["update_table_entry"];
					$update_field_name =$databindings[$property]["update_field_name"];
					$addition_rhs = $databindings[$property]["addition_rhs"];
					$addition_lhs = $databindings[$property]["addition_lhs"];
					
					$code = "";
					if(trim($update_where_sql) == "")
					{
						//just use the ids of the original variable itself.. no additinal queries..
						$code .= "\$updating_ids = array(\$data_id);\n";
					}
					else
					{
						$the_sql = "SELECT ".$update_select_sql." FROM ".$from_sql." WHERE ".$update_where_sql;
		
						$code .= "\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
						$code .= "	\$query .= \"".$addition_lhs." = '\". \$data_id.\"'\";";
						
						$code .= "// execute query\n";
						$code .= "\$result = mysql_query(\$query) or die (\"Error in query: \$query \".mysql_error()); \n";
						$code .= "\$updating_ids = array();\n";
						$code .= "\$i = 0;\n";
						$code .= "if(mysql_num_rows(\$result) > 0) \n";
						$code .= "{\n";
						$code .= "	while(\$row = mysql_fetch_row(\$result)) \n";
						$code .= "	{\n";
						$code .= "		// set the text\n";
						$code .= "		\$updating_ids[\$i] = \$row[0]; // this will give an id\n";
						$code .= "		\$i ++;\n";
						$code .= "	}\n";
						$code .= "} \n";
					}
					//we now we have updating ids in \$updating_ids now just enter it what else...
					//here we are introducing add/remove parameter..
					$code .= "if(\$add_remove != 'false') //mean it is adding\n";
					$code .= "{\n";
					
					$the_sql = "INSERT INTO ".$update_table. " VALUES";
						
					$code .= "	\$query = \"".$the_sql."\";\n"; // here $the_sql will be a constant for the code.
					$code .= "	\$rhs = \$value;\n";
					
					$code .= "	foreach(\$updating_ids as \$updating_id)\n";
					$code .= "	{\n";
					$code .= "		\$this_query = \$query.\" ( \".\$updating_id.\",'\".\${rhs}.\"')\";\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";		
								
					$code .= "}\n";
					$code .= "else\n";
					$code .= "{\n";
					
					$the_sql = "DELETE FROM ".$update_table_entry." WHERE ";
					$the_sql .= $update_field_name. " = '\${value}' AND ";
					$code .= "	\$query = \"".$the_sql."\";\n";
					$code .= "	foreach(\$updating_ids as \$updating_id)\n";
					$code .= "	{\n";
					$code .= "		\$this_query = \$query.\" ${update_table_entry}.id = \$updating_id \";\n";
					$code .= "		\$result = mysql_query(\$this_query) or die (\"Error in query: \$this_query \".mysql_error()); \n";	
					$code .= "	}\n";
					$code .= "}\n";
					
					// we are done.. with this..
					$this->databinding_updater .= $code;
					$this->databinding_updater .= "  \$update_query = NULL;\n";
						
				}
				else
				{
					$this->databinding_updater .= "  \$update_query = \"".$update_query."\";\n";
				}
				$this->databinding_updater .= "}\n";
				
				$i ++;
			}
		}
		
		$this->databinding_updater .= "\n";
		$this->databinding_updater .= "if(\$update_query != NULL)\n";
		$this->databinding_updater .= "{\n";
		$this->databinding_updater .= 
			" \$result = mysql_query(\$update_query) or die (\"Error in query: \$update_query \".mysql_error());\n";
		$this->databinding_updater .= "}\n"; //close for the inner IF..
		$this->databinding_updater .= "}\n"; //close for the function..
	}
	
	private function load_module_info()
	{
		//echo "project home:".$this->project_home."\n";
		$files = array();
		$d = dir($this->project_home);
		// Loop through all of the files:
		$i = 0;
		while (false !== ($file = $d->read()))
		{
			// If the file is not this file, and does not start with a '.' or '~'
			// and does not end in LCK, then store it for later display:
			if ( ($file{0} != '.') &&
				 ($file{0} != '~') &&
				 (substr($file, -3) != 'php') && 
				 (substr($file, -3) != 'xml') )
			{
				if($file == "store")
				{
					continue;
				}
				$files[$i++] = $file;
			}
		}
		
		$table_info = array();
			
		foreach($files as $file)
		{
			$module_name = $file;
			$module_xml = $this->project_home.$file."/"."module.xml";
			
			$doc = new DOMDocument();
			$doc->load($module_xml);
			
			if($doc == NULL || $doc->documentElement == NULL)
			{
				continue;
			}
			$table_elements = $doc->documentElement->childNodes;
			
			foreach ($table_elements as $table_element)
			{
				if($table_element->nodeType != XML_ELEMENT_NODE)
				{
					continue;
				}
				$table_name = $module_name."_".$table_element->getAttribute("name");
					
				$table_info[$table_name] = array();
				$field_elements = $table_element->childNodes;
				
				$is_interface = $table_element->getAttribute("interface");
				if($is_interface == "yes")
				{
					continue;
				}
				$all_fields = array();
				$direct_fields = array();
				
				$field_elements = $table_element->childNodes;
				
				foreach($field_elements as $field_element)
				{		
					if($field_element->nodeType != XML_ELEMENT_NODE)
					{
						continue;
					}
					if($field_element->tagName != "field")
					{
						continue;
					}
					$field_info = array(
							"name"=> $field_element->getAttribute("name"),
							"type"=> $field_element->getAttribute("type"),
							"isarray"=> $field_element->getAttribute("isarray"));
					
					$direct_fields[$field_element->getAttribute("name")] = 1;
					$all_fields[count($all_fields)] = $field_info;		
				}
				
				//load all the inherited information..
				$inherited_elements = $table_element->childNodes;
				foreach($inherited_elements as $inherited_element)
				{
					if($inherited_element->tagName != "inherited")
					{
						continue;
					}
					$inherited_table = $inherited_element->nodeValue;
					$pos = strpos($inherited_table, ".");
					$inherited_table_owner_module = substr($inherited_table, 0, $pos);
					$inherited_table_name = trim(substr($inherited_table, $pos+1));
					
					
					$inherited_module_xml = $this->project_home.trim($inherited_table_owner_module)."/module.xml";
					$inherited_doc = new DOMDocument();
					$inherited_doc->load($inherited_module_xml);
					
					
					$inherited_table_elements = $inherited_doc->documentElement->childNodes;
					foreach ($inherited_table_elements as $inherited_table_element)
					{
						if($inherited_table_element->nodeType != XML_ELEMENT_NODE)
						{
							continue;
						}
						if($inherited_table_element->getAttribute("name") == $inherited_table_name)
						{
							$inherited_field_elements = $inherited_table_element->childNodes;
							/*$inherited_field_elements = 
								array_merge($inherited_field_elements, $field_elements);*/
							foreach($inherited_field_elements as $inherited_field_element)
							{			
								if($inherited_field_element->tagName != "field")
								{
									continue;
								}
								$name = $inherited_field_element->getAttribute("name");
								if($direct_fields[$name] == 1)
								{
									continue;
								}
								$field_info = array(
										"name"=> $inherited_field_element->getAttribute("name"),
										"type"=> $inherited_field_element->getAttribute("type"),
										"isarray"=> $inherited_field_element->getAttribute("isarray"));
								
								$all_fields[count($all_fields)] = $field_info;
							}
							break;
						}
					}
				}
				
				
					
				foreach($all_fields as $field)
				{
					$field_name = $field["name"];
					$field_type = $field["type"];
					
					$is_array = $field["isarray"];
					
					$table_info[$table_name][$field_name] = array();
					$table_info[$table_name][$field_name]["type"] = $field_type;
					
					$istable = substr($field_type, 0, 5);
					if(trim(strtolower($istable)) == "table")
					{
						$field_type = substr($field_type, 6);
						$associated_table_name = str_replace(".", "_", $field_type);
						$table_info[$table_name][$field_name]["table"] = $associated_table_name;
					}
			
					if($is_array)
					{
						$table_info[$table_name][$field_name]["array"] = true;
					}
				}
				$table_info[$table_name]["id"] = array(); //just for the completeness
				$table_info[$table_name]["id"]["type"] = "INT";
				
				$table_info[$table_name]["extra"] = array(); //just for the completeness
				$table_info[$table_name]["extra"]["type"] = "TEXT";
			}
		}
		$this->table_info = $table_info;
	}
	
	private function parse_params($param_tree, $tokens, $lang)
	{
		//print_r($param_tree);
		if($param_tree-> type == statement::$PARAMS)
		{
			$param_count = count($param_tree->childs);
			$this-> param_parser_count = 0;
			for($i = 1; $i <= $param_count; $i ++)
			{
				$param_out = "";
				$param = $param_tree->childs["expr".$i];
				//print_r($param);
				if($lang == "js")
				{
					$param_out = $this->evaluate_expression_for_js($param, $tokens);
				}
				elseif($lang == "php")
				{
					$param_out = $this->evaluate_expression_for_php($param, $tokens);
				}
				$this-> param_parser_count ++;
				
				$id = $i - 1;
				$ret_val[$id] = $param_out;
			}
			return $ret_val;
		}
		return array();
	}
	
	public function get_project_home()
	{
		return $this->project_home;
	}
}
?>
